openmp: увеличение количества потоков снижает производительность

У меня есть этот код C ++.

Цикл проходит через матрицу, находит элемент min в каждой строке и вычитает его из каждого элемента соответствующей строки.
Переменная myr является суммой всех минимальных элементов

Попытка провести параллель для:

int min = 0;
int myr = 0;
int temp[SIZE][SIZE];
int size = 0;
...//some initialization

omp_set_num_threads(1);
start_time = omp_get_wtime();
#ifdef _OPENMP
#pragma omp parallel for firstprivate(min, size) reduction(+:myr)
#endif
for(int i = 0; i < size; i++){
min = INFINITY;
for(int j = 0; j < size; j++){
if (temp[i][j] < min)
min = temp[i][j];
}
myr+=min;
for(int j = 0; j < size; j++)
temp[i][j]-=min;
}
end_time = omp_get_wtime();

если я поставлю omp_set_num_threads(2); эта часть кода начинает работать медленнее.

Мой процесс имеет 2 ядра

Почему код работает медленнее с 2 потоками?

3

Решение

Должен быть какой-то псевдоним или что-то в этом роде. Сделайте вещи проще для OpenMP:

int const size0 = size;
#ifdef _OPENMP
#pragma omp parallel for reduction(+:myr)
#endif
for(int i = 0; i < size0; i++){
int min = INFINITY;
int * tmp = temp[i];
for(int j = 0; j < size0; j++){
if (tmp[j] < min)
min = tmp[j];
}
for(int j = 0; j < size0; j++)
tmp[j]-=min;
myr+=min;
}

То есть большинство переменных локальных и const если можешь.

3

Другие решения

Параллельную часть можно интерпретировать следующим образом (я использовал фрагмент @ jens-gustedt, но, по моему опыту, это не имело большого значения):

#pragma omp parallel private(myr_private) shared(myr)
{
myr_private = 0;
#pragma omp for
for(int i = 0; i < size; i++){
int min = INFINITY;
int * tmp = temp[i];
for(int j = 0; j < size; j++){
if (tmp[j] < min)
min = tmp[j];
}
for(int j = 0; j < size; j++)
tmp[j]-=min;
myr_private+=min;
}
#pragma omp critical
{
myr+=myr_private;
}
}

(Эта интерпретация прямо из http://www.openmp.org/mp-documents/OpenMP3.1.pdf Пример А.36.2с).
Если число потоков равно n> 1, то при #pragma omp parallel создает дополнительные потоки и затем в критической секции, которую все потоки должны ждать.

Я экспериментировал с матрицами разных размеров, и в моих ограниченных тестах два потока значительно быстрее с размерами выше 1000 и начинают отставать с размерами ниже 500.

0

По вопросам рекламы [email protected]