Domanda

Basta scrivere un piccolo test omp, e non funziona correttamente tutti i tempi:

#include <omp.h>
int main() {
  int i,j=0;
#pragma omp parallel
  for(i=0;i<1000;i++)
  {
#pragma omp barrier
    j+= j^i;
  }
  return j;
}

L'utilizzo di j per la scrittura di tutte le discussioni è corretto in questo esempio, MA

  • ci deve essere solo un valore deterministico di j

  • Ho un congelamento.

Compilato con gcc-4.3.1 -fopenmp a.c -o gcc -static

Esegui sul server a 4-core x86_Core2 Linux: $ ./gcc e congelare ottenuto (a volte; come 1 blocco per 4-5 corse veloci)

.

Strace:

[pid 13118] futex(0x80d3014, FUTEX_WAKE, 1) = 1
[pid 13119] <... futex resumed> )       = 0
[pid 13118] futex(0x80d3020, FUTEX_WAIT, 251, NULL <unfinished ...>
[pid 13119] futex(0x80d3014, FUTEX_WAKE, 1) = 0
[pid 13119] futex(0x80d3020, FUTEX_WAIT, 251, NULL                       
                        <freeze>

Perché ho un congelamento (deadlock)?

È stato utile?

Soluzione

Prova fare i privati ??in modo che ogni ciclo ha la sua propria copia.

Ora che ho più tempo, cercherò di spiegare. Con le variabili predefinite in OpenMP sono condivisi. Ci sono un paio di casi in cui ci sono valori predefiniti che rendono variabili private. regioni parallele non è uno di loro (così la risposta di High Performance Mark è sbagliato). Nel programma originale, si hanno due condizioni di gara - uno su i e uno su j. Il problema è con quello sulla i. Ogni thread eseguirà il ciclo determinato numero di volte, ma dato che viene modificata da ciascun filo, il numero di volte che un filo esegue il ciclo è indeterminato. Dal momento che tutte le discussioni devono eseguire il barrrier per la barriera da soddisfare, si arriva con il caso in cui si otterrà un blocco sulla barriera che non avrà mai fine, dal momento che non tutte le discussioni eseguirà lo stesso numero di volte.

Poiché l'OpenMP spec chiaramente (OMP spec V3.0, sezione 2.8.3 barriera Costrutto) che "la sequenza delle regioni Worksharing e regioni di barriera incontrati deve essere stessa cosa per ogni thread in una squadra", il programma non è conforme e come tale può avere un comportamento indeterminato.

Altri suggerimenti

Stai cercando di aggiungere alla stessa posizione da più thread. Non si può fare quello che stai cercando di fare in parallelo. Se si vuole fare una somma in parallelo, è necessario dividerlo in pezzi più piccoli e alla loro raccolta in seguito.

Aggiornamento di A5B: idea giusta, ma parte sbagliata del codice è stato avvistato. La variabile i viene modificata da entrambi i fili.

@ejd, Se io Mark I come private, sarà il mio programma sia conforme?

Sorry - Ho appena visto questa domanda. Tecnicamente, se si contrassegna variabile "i" come privato il programma sarà OpenMP compatibile. Tuttavia, v'è ancora una condizione di competizione su "j" e mentre il programma è compatibile (perché ci sono casi validi per avere condizioni di gara), il valore di "j" non è specificato (secondo le specifiche OpenMP).

In una delle risposte precedenti hai detto che stavi cercando di misurare la velocità di attuazione barriera. Ci sono diversi "parametri" che si potrebbe desiderare di guardare i risultati a che hanno pubblicato per una serie di costrutti OpenMP. Uno è stato scritto da Mark Bull (EPCC, Università di Edimburgo), un'altra (Sfinge) proviene da Lawrence Livermore National Labs (LLNL), e la terza (Parkbench) proviene da una Computing Partnership giapponese. Essi possono offrire qualche indicazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top