openmp critico
Seguendo questa domanda , per il codice seguente ( dall'esempio di documenti di 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);
}
Posso rimuovere l'esterno se provo e fallo
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];
}
}
Risposte
Puoi, ma questo si traduce efficacemente in un'esecuzione sequenziale. I thread sono costantemente in attesa di entrare nella sezione critica in modo che un solo thread alla volta esegua il corpo del ciclo. Quindi, si ottengono le stesse prestazioni (forse anche peggiori a causa dell'overhead di sincronizzazione) rispetto a un semplice loop seriale.
L'esempio dei documenti MS si sincronizza solo se è stato rilevato un nuovo valore massimo. Ciò consente di elaborare tutti i valori inferiori fino a questo punto in parallelo.
Come suggerito nei commenti, usa un costrutto di riduzione.