2016-02-12 21 views
6

Ho una domanda su come produrre pseudocodice OpenMP quando si ha in mente un grafico di dipendenza specifico. Quindi supponiamo di avere questo grafico specifica:Produrre codice di dipendenza dato codice OpenMP

Dependence graph

Una soluzione potrebbe essere qualcosa di simile:

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

Ora la cosa è che anche se il codice di cui sopra non avere successo importante parallelismo, compito e deve attendere che l'attività D sia completata e il compito F deve attendere l'esecuzione dell'attività B, che non è richiesta in base al grafico.

Quindi la mia domanda è: qualcuno può fornirmi uno pseudocodice OpenMP dove E non aspetterà che D e F non attenderanno B per il dato grafico delle dipendenze?

risposta

4

A tale scopo, lo standard OpenMP propone la clausola depend per la direttiva task.

Nel vostro caso specifico, credo che questo potrebbe essere utilizzato in questo modo:

#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; 
} 

Come potete vedere, ho introdotto alcune variabili a, b e c che io uso per definire le dipendenze tra i compiti. Li modifico anche nella chiamata di conseguenza, anche se questo non è necessario (l'ho fatto solo per mostrare come è stato gestito il flusso).

E qui è quello che ho sulla mia macchina:

~/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

Sì, che sembra funzionare perfettamente. Grazie! – blaze9