2016-05-25 6 views
1

Ich habe die FunktionZählen funktioniert nicht richtig in OpenMP

void collatz(int startNumber, int endNumber, int* iter, int nThreads) 
{ 
    int i, n, counter; 
    int isodd; /* 1 if n is odd, 0 if even */ 
    #pragma omp parallel for 
    for (i = startNumber; i <= endNumber; i++) 
    { 
     counter = 0; 
     n = i; 
     omp_set_num_threads(nThreads); 
     while (n > 1) 
     { 
      isodd = n%2; 
      if (isodd) 
       n = 3*n+1; 
      else 
       n/=2; 
      counter++; 
     } 
     iter[i - startNumber] = counter; 
    } 
} 

Es funktioniert, wie ich will, wenn die serielle ausgeführt (das heißt ohne OpenMP Kompilieren oder #pragma omp parallel for und omp_set_num_threads(nThreads); kommentieren out). Die parallele Version erzeugt jedoch das falsche Ergebnis, und ich denke, das liegt daran, dass die counter-Variable am Anfang jeder for-Schleife auf Null gesetzt werden muss und möglicherweise ein anderer Thread mit dem nicht nullten counter-Wert arbeiten kann. Aber selbst wenn ich #pragma omp parallel for private(counter) verwende, tritt das Problem immer noch auf. Was vermisse ich?

Ich kompiliere das Programm als C89.

+0

Versuchen Sie 'private (counter, n, isodd)' zu Ihrer OpenMP 'parallelen' Direktive hinzuzufügen ... – Gilles

+0

Dies löst das Problem. Bitte stelle es in eine Antwort, damit ich es annehmen kann. –

Antwort

2

Innerhalb Ihrer parallelen OpenMP-Region weisen Sie den Skalarvariablen counter, n und isodd Werte zu. Diese können daher nicht nur shared sein, wie sie standardmäßig sind. Sie müssen ihnen besondere Aufmerksamkeit schenken.

Eine schnelle Analyse zeigt, dass ihre Werte nur innerhalb des parallelen Bereichs und nur für den aktuellen Thread bedeutungsvoll sind. Daher wird klar, dass sie private lauten müssen.

Das Hinzufügen einer private(counter, n, isodd)-Klausel zu Ihrer #pragma omp parallel-Anweisung sollte das Problem beheben.