2011-11-17 12 views
5

Secondo il OpenMP Memory Model, la segue non è corretto:accesso alla memoria privata di un thread in OpenMP

int *p0 = NULL, *p1 = NULL; 
#pragma omp parallel shared(p0,p1) 
{ 
    int x; 
    // THREAD 0    // THREAD 1 
    p0 = &x;     p1 = &x; 
    *p1 ...     *p0 ... 
} 

Il mio esempio è simile al seguente però:

int *p0 = NULL, *p1 = NULL; 
#pragma omp parallel shared(p0,p1) 
{ 
    int x; 
    // THREAD 0    // THREAD 1 
    p0 = &x;     p1 = &x; 
    #pragma omp flush 

    #pragma omp barrier 
    *p1 ...     *p0 ... 
    #pragma omp barrier 
} 

Questo sarebbe errato? Non riesco a trovare qualcosa nel modello di memoria che non consentirebbe questo.

Suppongo che il mio esempio di giocattolo sia corretto, poiché nel modello di memoria in 3.1 consentono a un task di accedere a una variabile privata fintanto che il programmatore si accerta che sia ancora vivo. Dato che le attività possono essere slegate, possono in teoria essere eseguite all'interno di un thread di lavoro diverso, consentendo quindi a un thread OpenMP di accedere alla memoria privata di un'altra.

risposta

1

Questo dovrebbe funzionare. Flush sincronizza tutte le variabili condivise e garantisce che l'ambiente mp con tutti i thread sia ancora attivo. Finché non si usa p0 nell'assegnazione di p1s o viceversa, dovrebbe andare bene. Anche se non riesco a immaginare perché uno farebbe qualcosa di simile. Forse puoi dire di più sul ragionamento dietro quel costrutto.

Dal p0 e p1 sono ancora vivi dopo la regione in parallelo, si potrebbe fare tutte le assegnazioni anche lì senza barriere, ecc ..

+0

Sto provando a scrivere nello spazio indirizzo del thread 0 dal thread 1 e viceversa. Posso pensare ad alcune applicazioni interessanti ma non ho ancora un esempio concreto. Sto solo sperimentando. Si noti che sto dando a ogni thread l'accesso alla memoria privata di un altro thread. Voglio solo sapere se è esplicitamente respinto o scoraggiato; il modello di memoria OpenMP non è cristallino e se capisco le complessità con il pragma dell'attività, allora potrebbe essere che il modello di memoria è incompleto. – ipapadop

1

come un pensiero laterale, questo è analogo al tentativo di leggere una variabile locale all'interno di alcuni funzione che hai chiamato assegnando quella variabile locale a una variabile globale, quindi leggendo la variabile globale.

L'analogia qui è che una variabile globale agisce come una variabile condivisa nel multithreading, essenzialmente dando accesso a quello che doveva essere privato del thread (come la variabile locale che dovrebbe essere visibile solo all'interno della funzione).

Quindi, per rispondere alla domanda come richiesto, effettuare il dereferenziamento nella memoria privata del thread è completamente valido. È consentito perché l'alias del puntatore è consentito (questo è il caso in cui 2 o più variabili forniscono accesso alla stessa posizione in memoria, nel tuo caso uno è un intero privato thread e l'altro è un puntatore condiviso).

Anche se completamente valido, fare attenzione a ciò può causare alcune difficili condizioni di competizione, poiché in genere non si utilizza un blocco per proteggere l'accesso alle variabili private del thread.

+0

+1 per menzionare l'alias del puntatore. Tuttavia, non è ancora chiaro se quello che sto facendo è valido sotto il modello di memoria. Ha funzionato per me su tutti i compilatori/piattaforme che ho usato, tuttavia ciò non significa che sia corretto. – ipapadop

Problemi correlati