2016-03-31 2 views
5

Ich versuche, openmp Aufgaben verwenden, um eine gekachelte Ausführung der grundlegenden jacobi2d Berechnung planen. In jacobi2d gibt es eine Abhängigkeit von einem (i, j) vonDepend-Klausel in Openmp ist nicht respektieren Abhängigkeit erklärt

A (i, j)
A (i-1, j)
A (i + 1, j)
A (i, j-1)
A (i, j + 1).

Zu meinem Verständnis der Abhängigkeitsklausel erkläre ich die Abhängigkeiten korrekt, aber sie werden nicht respektiert, während der Code ausgeführt wird. Ich habe das vereinfachte Codestück unten kopiert. Zuerst vermutete ich, dass die Out-of-bounds für einige Kacheln dieses Problem verursachen könnten, also habe ich das korrigiert, aber das Problem bleibt bestehen (ich habe den längeren Code mit korrigierten Kacheln nicht kopiert, da dieser Teil nur aus ifs + besteht)

max)
int n=8,tsteps=2,b=4;   //n - size of matrix, tsteps - time iterations, b - tile size or block size 

#pragma omp parallel 
{ 
#pragma omp master 
for (t=0; t<tsteps; ++t) 
    { 
    for (i=0; i<n; i+=b) 
     for (j=0; j<n; j+=b) 
     { 
     #pragma omp task firstprivate(t,i,j) depend(in:A[i-1:b+2][j-1:b+2]) depend(out:B[i:b][j:b]) 
     { 
      #pragma omp critical 
      printf("t-%d i-%d j-%d --A",t,i,j);  //Prints out time loop, i,j 
     } 
     } 
    for (i=0; i<n; i+=b) 
     for (j=0; j<n; j+=b) 
     { 
     #pragma omp task firstprivate(t,i,j) depend(in:B[i-1:b+2][j-1:b+2]) depend(out:A[i:b][j:b]) 
     { 
      #pragma omp critical 
      printf("t-%d i-%d j-%d --B",t,i,j);  //Prints out time loop, i,j 
     } 
     } 
    } 
} 
} 

So ist die Idee mit der Abhängigkeit von i-1 ausgehend erklärt und j-1 und dem Bereich Wesen (b + 2) besteht darin, dass die benachbarten Fliesen auch Ihre aktuellen Fliesen Berechnungen beeinflussen. Und ebenso für den zweiten Satz von Schleifen, wo Werte in A nur dann überschrieben werden sollten, wenn die benachbarten Kacheln die Werte verwendet haben.

Code wird mit gcc 5.3 kompiliert, das openmp 4.0 unterstützt.

ps: Der oben angegebene Array-Bereich bezeichnet die Startposition und die Anzahl der zu berücksichtigenden Indizes beim Erstellen des Abhängigkeitsgraphen.

bearbeiten (basierend auf Zulans Kommentar) - den inneren Code in eine einfache print-Anweisung geändert, da dies ausreicht, um die Reihenfolge der Taskausführung zu überprüfen. Im Idealfall für die obigen Werte (da es nur 4 Kacheln gibt), sollten alle Kacheln den ersten Druck vervollständigen und dann nur den zweiten ausführen. Aber wenn Sie den Code ausführen, wird die Reihenfolge gemischt.

+0

Warum verwenden Sie nicht einfach die Arbeitsfreigabe in den Schleifen? In der ersten Schleife liest man von 'B', schreibt aber auf' A'. In der zweiten Schleife schreibst du auf "A" und liest von "B". Also mach part1 zuerst parallel und dann part2 parallel. Stellen Sie nur sicher, dass Sie die Threads zwischen part1 und part2 synchronisieren (was eigentlich implizit sein sollte, wenn Sie 'nowait' nicht verwenden). –

+1

Sicher sind die Bedingungen alle falsch? ("if ((ii! = 0 || ii! = n-1) || (jj! = 0 || jj! = n-1))". Betrachte ii == 0, das wird immer noch seit 0 ausgeführt! = n-1, aber Sie wollen es nicht, da es einen Out-of-bounds-Zugriff generiert ... –

+0

@Zboson - Ja, das kann auch getan werden, nur das Verwenden von Aufgaben gibt Ihnen einen etwas effizienteren Einsatz als ideal kleinere Aufgaben geben Ihnen eine höhere Parallelität und weniger Synchronisation erforderlich ist. @ Jim. Ja, Sie haben Recht, das ist ein Fehler mit dem Code. Die Sache ist das Abhängigkeitsproblem noch besteht. Ich verfolgt die Abhängigkeit und Ausführungsreihenfolge mit a Einfacher Druck vor den 2 inneren ii und jj für Schleifen und die Reihenfolge der Druckanweisungen ist falsch.Ich habe die Vorsichtsmaßnahme ergriffen, diesen Druck in ein kritisches Pragma zu bringen, da sonst der Druck wild falsch sein kann. – hajmola

Antwort

0

Also habe ich endlich das Problem herausgefunden, auch wenn OpenMP-Spezifikationen sagen, dass die dependence-Klausel mit einem Startpunkt und einem Bereich implementiert werden soll, wurde sie noch nicht in gcc implementiert. So vergleicht es derzeit nur den Startpunkt von der Abhängigkeitsklausel (abhängig (in: A [i-1: b + 2] [j-1: b + 2])) A [i-1] [j-1] in dieser Fall.

Zunächst habe ich Elemente in verschiedenen relativen Kachelpositionen verglichen. Vergleiche zB (0,0) Element mit dem letzten Element der Kachel, was keine Konflikte mit der Abhängigkeit und damit der zufälligen Reihenfolge der Ausführung verschiedener Aufgaben ergibt.

Die aktuelle gcc-Implementierung kümmert sich überhaupt nicht um den in der Klausel angegebenen Bereich.

Verwandte Themen