2016-02-12 8 views
6

Mam pytanie, jak utworzyć pseudokod OpenMP, gdy masz na myśli konkretny wykres zależności. Więc załóżmy, że mamy tego konkretnego wykresu:Tworzę kod OpenMP z grafem zależności

Dependence graph

Rozwiązaniem mogłoby być coś takiego:

#pragma omp parallel 
    { 
     #pragma omp single 
     { 
      A(); 
      #pragma omp task B(); 
      #pragma omp task C(); 
      D(); 
      #pragma omp taskwait 
      #pragma omp task E(); 
      F(); 
     } 
    } 

Teraz chodzi o to, że chociaż powyższy kod nie uda istotną równoległość, zadanie E musi czekać na zakończenie zadania D, a zadanie F musi czekać na zakończenie zadania B, co nie jest wymagane zgodnie z wykresem.

Moje pytanie brzmi, czy ktoś może mi podać pseudokod OpenMP, w którym E nie będzie czekać na D, a F nie będzie czekać na B dla danego wykresu zależności?

Odpowiedz

4

W tym celu standard OpenMP proponuje klauzulę depend dla dyrektywy .

W Twoim konkretnym przypadku, myślę, że to może być używane tak:

#include <stdio.h> 

int a, b, c; 

void A() { 
    a = b = c = 1; 
    printf("[%d]In A: a=%d b=%d c=%d\n", omp_get_thread_num(), a, b, c); 
} 

void B() { 
    a++; 
    sleep(3); 
    printf("[%d]In B: a=%d\n", omp_get_thread_num(), a); 
} 

void C() { 
    b++; 
    sleep(2); 
    printf("[%d]In C: b=%d\n", omp_get_thread_num(), b); 
} 

void D() { 
    c++; 
    sleep(1); 
    printf("[%d]In D: c=%d\n", omp_get_thread_num(), c); 
} 

void E() { 
    a++; 
    sleep(3); 
    printf("[%d]In E: a=%d, b=%d\n", omp_get_thread_num(), a, b); 
} 

void F() { 
    c++; 
    sleep(1); 
    printf("[%d]In F: b=%d c=%d\n", omp_get_thread_num(), b, c); 
} 

int main() { 

    #pragma omp parallel num_threads(8) 
    { 
     #pragma omp single 
     { 
      #pragma omp task depend(out: a, b, c) 
      A(); 
      #pragma omp task depend(inout: a) 
      B(); 
      #pragma omp task depend(inout: b) 
      C(); 
      #pragma omp task depend(inout: c) 
      D(); 
      #pragma omp task depend(inout: a) depend(in: b) 
      E(); 
      #pragma omp task depend(inout: c) depend(in: b) 
      F(); 
     } 
    } 
    printf("Finally a=%d b=%d c=%d\n", a, b, c); 

    return 0; 
} 

Jak widać, ja wprowadziłem pewne zmienne a, b i c którego używam do określenia zależności całej zadań. Zmienię je również odpowiednio w wywołaniu, chociaż nie jest to konieczne (zrobiłem to tylko po to, aby pokazać, w jaki sposób przetwarzano przepływ).

A oto co mam na moim komputerze:

~/tmp$ gcc -fopenmp depend.c 
~/tmp$ ./a.out 
[6]In A: a=1 b=1 c=1 
[7]In D: c=2 
[2]In C: b=2 
[6]In B: a=2 
[2]In F: b=2 c=3 
[6]In E: a=3, b=2 
Finally a=3 b=2 c=3 
+0

Tak, to wydaje się doskonale działa. Dziękuję Ci! – blaze9