5

Se uso una variabile condivisa, diciamo una doppia, per calcolare un qualche tipo di somma lungo l'esecuzione del programma. Ciò sarebbe in ogni caso vulnerabile a operazioni non stabili? Voglio dire, sarebbe possibile che più di un core acceda a questa variabile in modo asincrono e provochi risultati instabili?C++: Protezione memoria condivisa OpenMP

Ad esempio: questa è una variabile globale:

double totalTime = 0; 

e in ogni core un comando è chiamato:

totalTime += elapsedTime; 

Quest'ultima operazione/istruzione viene eseguita prendendo il valore di totalTime , mettilo nel registro della CPU e poi fai l'aggiunta. Posso immaginare che più di un core prenderebbe lo stesso valore nello stesso istante, e quindi aggiungere il nuovo tempo trascorso, e quindi il valore memorizzato in TotalTime verrebbe sovrascritto con il valore sbagliato, a causa della latenza. È possibile? e come posso risolvere questo?

Grazie.

risposta

4

Chiaramente questa operazione non è infallibile perché, come hai detto tu stesso, implica diverse istruzioni di assemblatore. In effetti, openMP ha persino una direttiva speciale per questo tipo di operazioni.

sarà necessario il atomic pragma per farlo, bene, "atomica":

#pragma omp atomic 
totalTime += elapsedTime; 

Nota che atomic funziona solo quando si dispone di un singolo aggiornamento ad una locazione di memoria, come un'aggiunta, incremento, ecc .

Se si dispone di una serie di istruzioni che devono atomica insieme è necessario utilizzare la direttiva critical:

#pragma omp critical 
{ 
    // atomic sequence of instructions 
} 

Edit: Ecco un buon suggerimento da "snemarch": Se state ripetutamente aggiornando la variabile globale totalTime in un ciclo parallelo si può considerare utilizzando la clausola reduction di automatizzare il processo e anche rendere molto più efficiente:

double totalTime = 0; 

#pragma omp parallel for reduction(+:totalTime) 
for(...) 
{ 
    ... 
    totalTime += elapsedTime; 
} 

Alla fine totalTime conterrà correttamente la somma dei valori locali elapsedTime senza necessità di sincronizzazione esplicita.

+0

Grazie, amico :) –

+0

Mi chiedo come OpenMP supporti l'aggiunta atomica per i tipi di dati in virgola mobile su x86 - non ci sono istruzioni native per questo. Sezioni critiche? – snemarch

+0

@snemarch: Non sono riuscito a trovare nulla di definitivo al riguardo, quindi credo che usi le serrature. – Tudor