2017-09-06 3 views
0

Alle Tutorial-Beispiele für Openmp, die ich sehe, sind zum Erstellen von Threads für For-Schleifen. Aber ich muss Threads für normale Gruppen von Anweisungen erstellen, die in Funktionen gruppiert werden können. zB etwa wie folgt:Erstellen von Openmp-Threads für Funktionen

#include <stdio.h> 
#include <omp.h> 
int A() { printf("in A:%d\n", omp_get_thread_num()); } 
int B() { printf("in B:%d\n", omp_get_thread_num()); } 
int D() { printf("in D:%d\n", omp_get_thread_num()); } 
int E() { printf("in E:%d\n", omp_get_thread_num()); } 
int F() { printf("in F:%d\n", omp_get_thread_num()); } 
int G() { printf("in G:%d\n", omp_get_thread_num()); } 
int H() { printf("in H:%d\n", omp_get_thread_num()); } 
int C() { 
    printf("in C:%d\n", omp_get_thread_num()); 
    #pragma omp parallel num_threads(2) 
    { 
     D(); // want to execute D,E in separate threads 
     E(); 
    } 
    F(); 
} 
main() { 
    omp_set_nested(1); 
    printf("in main:%d\n", omp_get_thread_num()); 
    G(); 
    #pragma omp parallel num_threads(3) 
    { 
     A(); // want to execute A,B,C in separate threads 
     B(); 
     C(); 
    } 
    H(); 
} 

In dem obigen Code, möchte ich jede Funktion genau einmal auszuführen, aber in verschiedenen Threads. (So ​​könnte ich falsch in dem obigen Code mit der Verwendung der Direktiven, bitte korrigieren Sie es bei Bedarf.)

Wie kann ich diese Art von verschachtelten Parallelität von Funktionen mit openmp? Werden diese Funktionen alle globalen Variablen teilen, die verfügbar sind, oder gibt es eine Möglichkeit anzugeben, welche Variablen von welchen Funktionen gemeinsam genutzt werden?

EDITS: Nachdem ich die Antwort von Jorge Bellon unten gelesen habe, habe ich folgendes codiert, und sein Ausgang wird nach dem Code angezeigt. Es sieht so aus, dass Thread-0 für viele der Funktionen verwendet wird, was nicht meine Absicht ist - ich möchte, dass die Funktionen parallel ausgeführt werden. Außerdem möchte ich nur eine Ausführung für G, also sieht es so aus, als müsste ich die "num_threads (3)" Zeile löschen. Lassen Sie mich wissen, was die Lösung für dieses Problem ist.

// compile this with: g++ -fopenmp 
int A() { printf("in H:%d\n", omp_get_thread_num()); sleep(1); } 
// similarly for B, D, E, F, G, H 
int C() { 
    printf("in C:%d\n", omp_get_thread_num()); sleep(1); 
    #pragma omp task 
    D(); 
    #pragma omp task 
    E(); 
    #pragma omp taskwait 
    F(); sleep(1); 
} 
main() { 
    omp_set_nested(1); 
    printf("in main:%d\n", omp_get_thread_num()); 
    #pragma omp parallel num_threads(3) 
    G(); 
    #pragma omp task 
    A(); 
    #pragma omp task 
    B(); 
    #pragma omp task 
    C(); 
    #pragma omp taskwait 
    H(); 
} 
// outputs: 
in main:0 
in G:1 
in G:0 
in G:2 
in A:0 
in B:0 
in C:0 
in D:0 
in E:0 
in F:0 
in H:0 

Antwort

1

Der beste Weg, diese Art von Code parallelisieren ist mit OpenMP task Konstrukten. Ihre parallele Region erstellt einen Pool von Threads, ein Master-Thread erstellt die äußeren Aufgaben und der Rest der Threads verarbeitet diese Aufgaben, sobald sie verfügbar sind.

Ob jede Funktion in einem anderen Thread ausgeführt wird, hängt vollständig vom Status des Programms zur Laufzeit ab. Dies bedeutet, dass einige Aufgaben in demselben Thread ausgeführt werden können, wenn alle anderen Threads beschäftigt sind, was kein besonderes Problem darstellt.

Sie können task dependences (ab OpenMP 4) verwenden, um zu steuern, ob eine Aufgabe zum Zeitpunkt der Erstellung ausgeführt werden darf.

+0

Danke. Ich habe deine Lösung versucht, aber es sieht so aus, als ob ich nur einen Thread bekomme. Bitte sehen Sie die Details in der obigen Frage hinzugefügt. – R71

+0

Ich brauche die Aufgaben nicht über einen lokalen Join hinaus, also brauche ich nicht die Details der Aufgabenabhängigkeiten. – R71

+0

Sie müssen den Bereich angeben, in dem die Threads parallel ausgeführt werden. In dem aufgabenbasierten Code, den du zeigst, ist der parallele Bereich nur 'G();'. Sie müssen spitze Klammern '{}' verwenden (siehe mein Beispiel), um festzulegen, dass der parallele Teil alle folgenden Zeilen bis zum Ende der Hauptfunktion enthält. Um zu wissen, ob Tasks parallel ausgeführt werden, fügen Sie den 'get_thread_num()' Rückgabewert zum 'printf' hinzu, damit Sie wissen, welcher Thread diese Aufgabe ausführt. –

0

Die folgende Lösung wird mit C++ 11 Threads implementiert. Eine detaillierte openmp-Version muss noch ausgearbeitet werden.

// compile this with: g++ -pthread -std=gnu++0x 
#include <stdio.h> 
#include <unistd.h> // for sleep 
#include <thread> 
#include <iostream> 
#include <sstream> 
using namespace std; 
int A() { stringstream ss; ss << this_thread::get_id(); 
      printf("in A:%s\n", ss.str().c_str()); sleep(1); } 
// similarly for B, D, E, F, G, H 
int C() { 
    stringstream ss; ss << this_thread::get_id(); 
    printf("in C:%s\n", ss.str().c_str()); sleep(1); 
    std::thread thread_1(D); 
    std::thread thread_2(E); 
    thread_1.join(); 
    thread_2.join(); 
    F(); sleep(1); 
} 
main() { 
    printf("in main\n"); 
    G(); 
    std::thread thread_1(A); 
    std::thread thread_2(B); 
    std::thread thread_3(C); 
    thread_1.join(); 
    thread_2.join(); 
    thread_3.join(); 
    H(); 
} 
// outputs: 
in main 
in G:0x600000060 
in A:0x60005aa10 
in B:0x60005ab10 
in C:0x60005ae40 
in D:0x60005af40 
in E:0x60005b040 
in F:0x60005ae40 
in H:0x600000060 
Verwandte Themen