2017-10-26 2 views
0

Bisher habe ich omp nur für große Zyklen verwendet, da es sehr einfach zu schreiben ist und diese Zyklen die meiste Zeit verbrauchen. Manchmal muss ich jedoch einige I/O-Operationen durchführen, die nur in einem Thread effizient durchgeführt werden können, aber normalerweise ist diese I/O unabhängig von der (nächsten) Schleife.Ist es möglich, später Threads in omp für cyclus hinzuzufügen?

Ich brauche so etwas wie dies zu tun:

print_something(); // independet 
print_something_else(); // independent 
for(...){...}; // large cycle independent on previous printing 

Wie omp verwenden print_something in einem Thread ausgeführt werden, print_something_else in zweiten Thread und verwenden, um alle verbleibenden Threads, die Schleife zu berechnen? Und weil die Schleife wird sehr wahrscheinlich mehr Zeit als die Ausführung von Druckfunktionen, wie die beiden Threads, die die I/O in die Schleife tun, nachdem sie fertig sind, hinzufügen?

Würde so etwas funktionieren?

#pragma omp parallel 
{ 
    #pragma omp sections 
    { 
     #pragma omp section 
     { 
      print_something(); 
     } 
     #pragma omp section 
     { 
      print_something_else(); 
     } 
    } 
    #pragma omp for 
    for(...){...}; 
} 

Antwort

2

Die #pragma omp section hat eine implizite Barriere, so wird die Anwendung warten, bis die Abschnitte vor beenden die #pragma omp for läuft. Eine Alternative wäre, die nowait-Klausel im Pragma-omp-Abschnitt hinzuzufügen. Dies wäre also eine Alternative zum Ausführen des Codes:

#pragma omp parallel 
{ 
    #pragma omp sections nowait 
    { 
     #pragma omp section 
     { 
      print_something(); 
     } 
     #pragma omp section 
     { 
      print_something_else(); 
     } 
    } 
    #pragma omp for 
    for(...){...}; 
} 

Dieser Ansatz hat jedoch ein Problem. Die #pragma omp for verwendet möglicherweise die statische Planung und das bedeutet, dass es die Arbeit auf der for-Schleife unter dem Team von Threads verteilen wird, und das schließt diejenigen ein, die die Abschnitte ausführen. In diesem Fall muss die Parallele auf den Abschluss der Abschnitte warten. Eine Möglichkeit zum Adressieren besteht darin, eine andere Planung für die for-Schleife zu verwenden (z. B. dynamisch oder geführt).

Wenn Ihr Compiler OpenMP-Aufgabenkonstrukte unterstützt, glaube ich, dass Sie mit diesen Aufgaben diese unregelmäßige Parallelität, die Sie suchen, besser ausdrücken können. Diese andere question in SO hat eine gute Antwort auf den Unterschied zwischen den Abschnitten und Aufgaben.

+0

Können Sie bitte mehr erklären, wie Sie Task Constructs verwenden? Ich habe Schwierigkeiten, sie richtig zu verstehen – Michal

Verwandte Themen