2016-08-17 6 views
0

Ich habe ein Problem mit OpenMP-Aufgaben. Ich versuche, parallele Version von "for" -Schleife mit omp-Aufgaben zu erstellen. Allerdings ist die Ausführungszeit dieser Version fast 2 Mal länger als die der Basisversion, für die ich omp verwende, und ich weiß nicht, was der Grund dafür ist. Schauen Sie sich Codes Balg:OpenMP-Task-Parallelität - Leistungsproblem

omp für Version:

t.start(); 
#pragma omp parallel num_threads(threadsNumber) 
{ 
    for(int ts=0; ts<1000; ++ts) 
    { 
     #pragma omp for 
     for(int i=0; i<size; ++i) 
     { 
      array_31[i] = array_11[i] * array_21[i]; 
     } 
    } 
} 
t.stop(); 
cout << "Time of omp for: " << t.time() << endl; 

omp Aufgabe Version:

t.start(); 
#pragma omp parallel num_threads(threadsNumber) 
{ 
    #pragma omp master 
    { 
     for(int ts=0; ts<1000; ++ts) 
     { 
      for(int th=0; th<threadsNumber; ++th) 
      { 
       #pragma omp task 
       { 
        for(int i=th*blockSize; i<th*blockSize+blockSize; ++i) 
        { 
         array_32[i] = array_12[i] * array_22[i]; 
        } 
       }      
      } 

      #pragma omp taskwait 
     } 
    } 
} 
t.stop(); 
cout << "Time of omp task: " << t.time() << endl; 

In der Aufgaben-Version i-Schleife in der gleichen Weise unterteilen, wie in omp für. Jede der Aufgaben muss dieselbe Anzahl von Iterationen ausführen. Die Gesamtanzahl der Aufgaben entspricht der Gesamtanzahl der Threads.

Performance-Ergebnisse:

Time of omp for: 4.54871 
Time of omp task: 8.43251 

Was kann ein Problem sein? Ist es möglich, eine ähnliche Leistung für beide Versionen zu erzielen? Angehängte Codes sind einfach, weil ich nur mein Problem darstellen wollte, das ich zu lösen versuche. Ich erwarte nicht, dass beide Versionen mir die gleiche Leistung geben, aber ich möchte den Unterschied reduzieren.

Danke für die Antwort. Mit freundlichen Grüßen.

Antwort

0

Ich denke, das Problem hier ist der Overhead. Wenn Sie eine Schleife als parallel deklarieren, weist sie alle Threads zu, die ihren Teil der for-Schleife gleichzeitig ausführen sollen. Wenn Sie eine Aufgabe starten, muss sie bei jedem Start einer Aufgabe den gesamten Prozess der Einrichtung durchlaufen. Warum nicht einfach folgendes tun.

#pragma omp parallel num_threads(threadsNumber) 
{ 
    #pragma omp master 
    { 
     for(int ts=0; ts<1000; ++ts) 
     { 
      #pragma omp for 
      for(int th=0; th<threadsNumber; ++th) 
      { 
        for(int i=th*blockSize; i<th*blockSize+blockSize; ++i) 
        { 
         array_32[i] = array_12[i] * array_22[i]; 
        }     
      } 


     } 
    } 
} 
0

Ich würde sagen, dass die Frage, die Sie hier experimentieren mit dem Daten Affinität verwandt ist: wenn Sie die #pragma omp for die Verteilung von Iterationen über Threads verwenden ist immer gleich für alle Werte von ts, während Bei Aufgaben haben Sie keine Möglichkeit, eine Bindung von Aufgaben an Threads anzugeben.

einmal gesagt, dass ich Ihr Programm in meiner Maschine mit drei Reihen von 1M Elemente und die Ergebnisse zwischen den beiden Versionen sind näher ausgeführt haben:

  • t1_for: 2.041443s
  • t1_tasking: 2.159012s

(ich verwendete GCC 5.3.0 20151204)