2016-10-06 5 views
0

In Anbetracht des folgenden Beispiels erfordert OpenMP, dass die in buff1 und buff2 gespeicherten Adressen ermittelt werden müssen. Die in buff1 und buff2 gespeicherten Adressen werden jedoch anhand der ID (myid) des Threads ermittelt, der die Task ausführt. Wie kann ich mein Problem lösen? Jede Lösung wird geschätzt. Ich darf keine Speicher zuordnen.OpenMP Task-Abhängigkeiten zu Thread-private Speicher

mystruct* buff1; 
mystruct* buff2; 
#pragma omp task depend(in: data[0:1000]) depend(inout: buff1[0:0]) 
{ 
    int myid=omp_get_thread_num(); 
    buff1=buffers[myid]; 
    processA(data, buff1); 
} 
#pragma omp task depend(in: data[0:1000]) depend(inout: buff2[0:0]) 
{ 
    int myid=omp_get_thread_num(); 
    buff2=buffers[myid]; 
    processB(data, buff2); 
} 
#pragma omp task depend(in: data[0:1000]) depend(inout: buff1[0:0]) depend(inout: buff2[0:0]) 
{ 
    processC(data, buff1, buff2); 
} 

Antwort

0

Taskabhängigkeiten werden registriert, wenn Tasks erstellt werden. Beachten Sie, dass sie erfüllt sein müssen, bevor Sie mit der Ausführung der Aufgabe beginnen. Daher ist das, wonach Sie fragen, nicht möglich.

Haben Sie in Betracht gezogen, die Abhängigkeiten über buff1 und buff2 direkt und nicht über den Inhalt zu definieren, auf den sie verweisen?

mystruct* buff1; 
mystruct* buff2; 
#pragma omp task depend(in: data[0:1000]) depend(inout: buff1) shared(buff1) 
{ 
    int myid=omp_get_thread_num(); 
    buff1=buffers[myid]; 
    processA(data, buff1); 
} 
#pragma omp task depend(in: data[0:1000]) depend(inout: buff2) shared(buff2) 
{ 
    int myid=omp_get_thread_num(); 
    buff2=buffers[myid]; 
    processB(data, buff2); 
} 
#pragma omp task depend(in: data[0:1000]) depend(inout: buff1, buff2) // shared(buff1, buff2) ??? 
{ 
    processC(data, buff1, buff2); 
} 

Es ist wichtig, den Unterschied der Bedeutung dieser beiden Klauseln zu beachten: depend(inout: buff1) und depend(inout: buff1[0:0]). Der erste definiert die Abhängigkeit von &buff1, während der zweite die Abhängigkeit von &buff1[0] = &(*(buff1 + 0)) = buff1 definiert. Im Allgemeinen wird die erste verwendet, wenn die Task den Wert des Zeigers selbst erzeugt (und normalerweise zusammen mit einer shared-Klausel verwendet wird), während die zweite verwendet wird, wenn die Task die Daten ändert, auf die der Zeiger zeigt.

Schließlich haben Sie die Datensharings von buff1 und buff2 Variablen nicht angegeben. Wenn die Änderungen, die Ihre Aufgaben an diesen Variablen vornehmen, von außerhalb sichtbar sein müssen, müssen Sie diese Variablen als gemeinsam kommentieren.