openmp kritisch
Befolgen Sie diese Frage für den folgenden Code ( aus dem Beispiel für MS OpenMP-Dokumente ).
// 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);
}
Kann ich die Außenseite entfernen, wenn testen und tun
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];
}
}
Antworten
Sie können, aber dies führt effektiv zu einer sequentiellen Ausführung. Die Threads warten ständig darauf, in den kritischen Abschnitt zu gelangen, sodass jeweils nur ein Thread den Schleifenkörper ausführt. Daher erhalten Sie die gleiche Leistung (möglicherweise sogar schlechter aufgrund des Synchronisationsaufwands) als eine einfache serielle Schleife.
Das Beispiel aus den MS-Dokumenten wird nur synchronisiert, wenn ein neuer Maximalwert festgestellt wurde. Dadurch können alle niedrigeren Werte bis zu diesem Punkt parallel verarbeitet werden.
Verwenden Sie, wie in den Kommentaren vorgeschlagen, ein Reduktionskonstrukt.