2011-10-05 11 views
6

Perché il compilatore intel non consente di specificare che alcune azioni in un blocco parallel for devono essere eseguite solo dal thread principale?il pragma "master" di OpenMP non deve essere racchiuso dal "parallelo per" pragma

E come posso fare quello che sto cercando di ottenere senza questo tipo di funzionalità?

Quello che sto cercando di fare è aggiornare una barra di avanzamento attraverso una richiamata in un parallelo per:

long num_items_computed = 0; 

#pragma omp parallel for schedule (guided) 
for (...a range of items...) 
{ 
    //update item count 
    #pragma omp atomic 
     num_items_computed++; 

    //update progress bar with number of items computed 
    //master thread only due to com marshalling 
    #pragma omp master 
     set_progressor_callback(num_items_computed); 

    //actual computation goes here 
    ...blah... 
} 

Voglio solo il thread principale per chiamare la callback, perché se io non rispettare tale (ad esempio utilizzando omp critical invece di garantire un solo thread utilizza il callback in una sola volta) ottengo la seguente eccezione di runtime:

The application called an interface that was marshalled for a different thread. 

... da qui il desiderio di mantenere tutte le richiamate nel thread master.

Grazie in anticipo.

risposta

6
#include <omp.h> 
void f(){} 
int main() 
{ 
#pragma omp parallel for schedule (guided) 
    for (int i = 0; i < 100; ++i) 
    { 
     #pragma omp master 
     f(); 
    } 
    return 0; 
} 

Errore del compilatore C3034 OpenMP 'master' direttiva non può essere annidato direttamente all'interno di 'parallelo per' direttiva Visual Studio 2010 OpenMP 2.0

può essere così:

long num_items_computed = 0; 

#pragma omp parallel for schedule (guided) 
for (...a range of items...) 
{ 
    //update item count 
    #pragma omp atomic 
     num_items_computed++; 

    //update progress bar with number of items computed 
    //master thread only due to com marshalling 
    //#pragma omp master it is error 
    //#pragma omp critical it is right 
    if (omp_get_thread_num() == 0) // may be good 
     set_progressor_callback(num_items_computed); 

    //actual computation goes here 
    ...blah... 
} 
+0

Questo sembra funzionare, grazie. Ero preoccupato che il thread principale potesse essere diverso da tutti i thread di lavoro ... quindi quella callback non sarebbe mai stata eseguita ... è pensabile all'interno della specifica omp? –

+0

Se il numero di iterazioni è elevato, non si noterà la differenza. E dopo l'aggiunta del ciclo: if (omp_get_thread_num() == 0) set_progressor_callback (num_items_computed); –

+0

da OpenMP standart su pragma omp parallel for(): "Il costrutto del ciclo specifica che le iterazioni di uno o più loop associati verranno eseguite in parallelo dai thread nel team nel contesto delle loro attività implicite.Le iterazioni sono distribuite su thread già esistenti nel team che esegue la regione parallela alla quale si lega l'area del loop. " –

3

Il motivo per cui l'errore si verifica perché il thread principale non è presente la maggior parte delle volte in cui il codice raggiunge la riga #pragma omp master. Per esempio, prendiamo il codice da Artyom:

#include <omp.h> 
void f(){} 
int main() 
{ 
#pragma omp parallel for schedule (guided) 
    for (int i = 0; i < 100; ++i) 
    { 
     #pragma omp master 
      f(); 
    } 
    return 0; 
} 

Se il codice si compila, quanto segue potrebbe accadere:

Diciamo filo 0 inizia (il filo maestro). Raggiunge il pragma che praticamente dice "Maestro, fai il seguente pezzo di codice". Essendo il master può eseguire la funzione. Tuttavia, cosa succede quando il thread 1 o 2 o 3, ecc, raggiunge quel pezzo di codice?

La direttiva master indica al team presente/in ascolto che il thread principale deve eseguire f(). Ma la squadra è un singolo thread e non c'è nessun master presente. Il programma non saprebbe cosa fare oltre quel punto.

Ed è per questo, penso, che al master non è consentito entrare nel ciclo for.

Sostituire master directive con if (omp_get_thread_num() == 0) funziona perché ora il programma dice "Se sei maestro, fallo, altrimenti ignora".