openmp критический
Aug 19 2020
Следуя этому вопросу , для кода ниже ( из примера документов MS OpenMP )
// omp_critical.cpp
// compile with: /openmp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int i;
int max;
int a[SIZE];
for (i = 0; i < SIZE; i++)
{
a[i] = rand();
printf_s("%d\n", a[i]);
}
max = a[0];
#pragma omp parallel for num_threads(4)
for (i = 1; i < SIZE; i++)
{
if (a[i] > max)
{
#pragma omp critical
{
// compare a[i] and max again because max
// could have been changed by another thread after
// the comparison outside the critical section
if (a[i] > max)
max = a[i];
}
}
}
printf_s("max = %d\n", max);
}
Могу ли я снять снаружи, если протестирую и сделаю
max = a[0];
#pragma omp parallel for num_threads(4)
for (i = 1; i < SIZE; i++)
{
#pragma omp critical
{
// compare a[i] and max again because max
// could have been changed by another thread after
// the comparison outside the critical section
if (a[i] > max)
max = a[i];
}
}
Ответы
1 cos_theta Aug 19 2020 at 16:53
Вы можете, но это фактически приводит к последовательному выполнению. Потоки постоянно ждут входа в критическую секцию, так что только один поток выполняет тело цикла за раз. Следовательно, вы получаете ту же производительность (возможно, даже хуже из-за накладных расходов на синхронизацию), чем простой последовательный цикл.
Пример из документации MS синхронизируется, только если обнаружено новое максимальное значение. Это позволяет обрабатывать все более низкие значения до этого момента параллельно.
Как предложено в комментариях, используйте редукционную конструкцию.