2016-05-03 17 views
0

In meiner Hauptfunktion eingestellt I:htop und OpenMP Threads

omp_set_num_threads(20); 

die OpenMP 20 Threads verwenden erzählt (haben 40 Threads zur Verfügung).

ich meinen Code dann ausführen, die die Richtlinie enthält:

#pragma omp parallel for shared(x,y,z) 

für das Haupt for-Schleife, und die CPU-Auslastung durch htop Monitor (vielleicht nicht die beste Art und Weise, aber immer noch). Es gibt 50 "Aufgaben", die die for-Schleife ausführen muss und die jeweils eine Weile dauern. Was ich durch htop beobachte, ist, dass nach Beendigung der Aufgaben die Anzahl der Threads sinkt. Genauer gesagt, erwarte ich, dass bei Verwendung von 20 Threads eine CPU-Auslastung von 2000% angezeigt wird, bis weniger als 20 Tasks übrig sind, nach denen sich die Threads "befreien" sollten. Was ich jedoch sehe, ist zuerst 2000%, und nachdem n Aufgaben abgeschlossen ist, sehe ich 2000% - (n * 100%) Leistung. So scheint es, dass die Threads beim Abschluss der Aufgaben heruntergefahren werden, anstatt neue Aufgaben zu übernehmen.

Ist dies, dass Sound ungerade erwartet oder tut werden?

+0

also nach 20 Aufgaben der CPU-Auslastung sinkt auf Null und Ihre parallele Schleife nie beendet? –

+0

Nein, es endet. Meine Frage ist, warum die Threads zu sterben scheinen, wenn noch Aufgaben zu bearbeiten sind. Da – user1938803

+1

50 geteilt durch 20 2.5 ist und der Standardschleife Planung mit den meisten Compilern ist 'static' daher die Hälfte der Fäden verarbeiten zwei Iterationen und die andere Hälfte - drei Iterationen. –

Antwort

1

Die standardmäßige parallele Schleifenplanung für praktisch alle vorhandenen OpenMP-Compiler lautet static, was bedeutet, dass die OpenMP-Laufzeit versucht, den Iterationsraum gleichmäßig auf die Threads aufzuteilen und eine statische Arbeitszuweisung vorzunehmen. Da Sie 50 Wiederholungen und 20 Threads, kann die Arbeit nicht in gleichem Maße wie 20 aufgeteilt wird 50 nicht teilen daher die Hälfte der Threads drei Iterationen tun, während die andere Hälfte zwei Wiederholungen tun.

Es gibt eine implizite Barriere am Ende des (kombinierten parallel) for Konstrukts, bei dem die Threads, die früher enden, auf den Abschluss der Threads warten. Abhängig von der OpenMP-Implementierung kann die Barriere als eine Warteschleife mit besetzt, als eine Warteoperation bei einem OS-Synchronisationsobjekt oder als eine Kombination von beiden implementiert werden. die CPU-Auslastung der Gewinde in den beiden letzten Fällen, dass die Barriere entweder getroffen wird sofort auf Null fallen, wie sie in unterbrechbare schlafen gehen oder werden zunächst bei 100% für eine kurze Zeit (die damit beschäftigt loop) bleiben und dann auf Null fallen (das Warten).

Wenn die Schleife Iterationen genau die gleiche Zeit nehmen, dann wird die CPU-Auslastung zunächst 2000% sein, dann nach zwei Iterationen (und ein bisschen mehr, wenn die Barriereimplementierung eine kurze Busy-Schleife verwendet) wird auf 1000% fallen. Wenn die Iterationen jeweils unterschiedlich lange dauern, kommen die Threads zu unterschiedlichen Zeitpunkten an der Barriere an und die CPU-Auslastung nimmt allmählich ab.

Auf jedem Fall verwenden schedule(dynamic) jede Iteration den ersten Thread gegeben zu haben, zur Verfügung zu stehen. Dies wird die CPU-Auslastung in dem Fall verbessern, wenn die Iterationen eine unterschiedliche Zeitdauer benötigen. Es hilft nicht, wenn die Iterationen jeweils die gleiche Zeit benötigen. Die Lösung in diesem letzteren Fall besteht darin, die Anzahl der Iterationen als ganzzahliges Vielfaches der Anzahl der Threads zu erhalten.