dlasalle ist korrekt über den tatsächlichen Fehler.
Es gibt jedoch zwei grundlegende Probleme bei der Verwendung von OpenMP-Aufgaben. Sie erzeugen innerhalb jedes rekursiven Aufrufs eine parallele Region. Dies bedeutet, dass Sie verschachtelte parallele Regionen verwenden. Standardmäßig ist verschachtelte Parallelität in OpenMP deaktiviert, und das ist hier nicht sinnvoll. Sie möchten, dass alle Aufgaben, die Sie während der Rekursion erzeugen, von demselben Thread-Pool ausgeführt werden. Um dies zu tun, müssen Sie die parallel
/single
außerhalb der Rekursion, z.
int reduce_par(int* arr, unsigned long int n)
{
int x;
if (n <= 0)
return 0;
#pragma omp task shared(x)
x = reduce_par(arr, n - 1) + arr[n - 1];
#pragma omp taskwait
return x;
}
int reduce(int* arr, unsigned long int n)
{
#pragma omp parallel
{
#pragma omp single nowait
{
reduce_par(arr, n);
}
}
}
Auch wenn dies nicht segfault, und selbst wenn man unendlich vielen Kern hatte, mit unendlicher Speicher-Bandbreite und keine Thread-Erzeugung Overhead, diese woudn't noch jede Leistung profitieren von der Parallelisierung bieten. Um dies herauszufinden, zeichnen Sie das Diagramm der Aufgaben und ihrer Operationen und fügen Sie die Abhängigkeiten hinzu. Versuchen Sie, die Knoten des Diagramms in einer Zeitachse anzuordnen, die die Aufgabenabhängigkeiten berücksichtigt, und sehen Sie, ob überhaupt etwas parallel berechnet werden kann. Die richtige Lösung für eine parallele Summierung ist ein parallel for
Worksharing-Konstrukt mit einer reduce
Klausel. Und wenn Sie Aufgaben verwenden mussten, müssen Sie Divide and Conquer verwenden, z. spawnen zwei Aufgaben für zwei Hälften des Arrays. Um eine angemessene Leistung zu erzielen, müssen Sie die Task-Erstellung/Rekursion bei einer minimalen Workload-Größe stoppen, um den Overhead überschaubar zu halten.
Wie wird 'n'' <0', wenn es 'unsigned' ist? – yano
erhöhen Sie Ihre Stackgröße und werfen Sie einen Blick auf 'OMP_STACKSIZE' – Gilles
Bitte formatieren Sie Ihren Code. Das ist so unnötig hässlich, es tut weh. – Zulan