2017-04-21 3 views
1

Ich versuche zu steuern, wo ich meinen MPI-Code ausführen. Dazu gibt es mehrere Wege, taskset, DLegen, numactl oder nur die Optionen von mpirun wie --bind-to oder -CPU-Set.Bind MPI-Prozesse, mit Null-Oversubscribe

Die Maschine: wird die gemeinsame Speicher, 16 Knoten, von 2 mal 12cores (so 24 Kerne pro Knoten)

> numactl -H 
    available: 16 nodes (0-15) 
    node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 192 193 194 195 196 197 198 199 200 201 202 203 
    node 1 cpus: 12 13 14 15 16 17 18 19 20 21 22 23 204 205 206 207 208 209 210 211 212 213 214 215 
    node 2 cpus: 24 25 26 27 28 29 30 31 32 33 34 35 216 217 218 219 220 221 222 223 224 225 226 227 
    ... (I reduce the output) 
    node 15 cpus: 180 181 182 183 184 185 186 187 188 189 190 191 372 373 374 375 376 377 378 379 380 381 382 383 
    node distances: 
    node 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    0: 10 50 65 65 65 65 65 65 65 65 79 79 65 65 79 79 
    1: 50 10 65 65 65 65 65 65 65 65 79 79 65 65 79 79 
    2: 65 65 10 50 65 65 65 65 79 79 65 65 79 79 65 65 
    3: 65 65 50 10 65 65 65 65 79 79 65 65 79 79 65 65 
    4: 65 65 65 65 10 50 65 65 65 65 79 79 65 65 79 79 
    5: 65 65 65 65 50 10 65 65 65 65 79 79 65 65 79 79 
    6: 65 65 65 65 65 65 10 50 79 79 65 65 79 79 65 65 
    7: 65 65 65 65 65 65 50 10 79 79 65 65 79 79 65 65 
    8: 65 65 79 79 65 65 79 79 10 50 65 65 65 65 65 65 
    9: 65 65 79 79 65 65 79 79 50 10 65 65 65 65 65 65 
10: 79 79 65 65 79 79 65 65 65 65 10 50 65 65 65 65 
11: 79 79 65 65 79 79 65 65 65 65 50 10 65 65 65 65 
12: 65 65 79 79 65 65 79 79 65 65 65 65 10 50 65 65 
13: 65 65 79 79 65 65 79 79 65 65 65 65 50 10 65 65 
14: 79 79 65 65 79 79 65 65 65 65 65 65 65 65 10 50 
15: 79 79 65 65 79 79 65 65 65 65 65 65 65 65 50 10 

Mein Code verwenden, nicht den Vorteil des gemeinsamen Speichers nehmen, Ich mag würde es ist wie auf verteilten Speicher. Aber die Prozesse scheinen sich zu bewegen und zu weit von ihren Daten entfernt zu sein, also möchte ich sie binden und sehen, ob die Leistung besser ist.

Was ich versuche haben bisher:

der klassische Anruf mpirun -np 64 ./myexec param> logfile.log

Jetzt habe ich den Lauf auf den letzten Knoten binden wollte, können sagen, 12 bis 15, mit DLegen oder numactl (I nicht wesentlichem Unterschied sehen Sie ...)

mpirun -np 64 DLegen -c144-191,336-383 ./myexec param> logfile.log

mpirun -NP 64 numactl --physcpubind = 144-191,336-383 -l ./myexec param> logfile.log

(Der Hauptunterschied der beiden ist die -l von numactl dass 'gebunden' der Speicher, aber ich bin nicht einmal sicher, dass es einen Unterschied macht ..)

Also beide funktionieren gut, die Prozesse sind begrenzt, wo ich wollte, ABER durch näher zu jedem Prozess, scheint es, dass einige sind auf demselben Kern verteilt! Sie verwenden also nur jeweils 50% des Kerns! Dies geschieht auch dann, wenn die Anzahl der verfügbaren Core größer ist als die Anzahl der Prozesse! Das ist überhaupt nicht gut.

Also versuche ich einige mpirun optin wie --nooversubscribe hinzufügen, aber es ändert sich nichts ... Ich verstehe das nicht. Ich versuche auch mit --bind-to-none (um Konflikt zwischen mpirun und dplace/numactl zu vermeiden), -cpus-pro-proc 1 und -cpus-pro-rank 1 ... nicht lösen.

Also habe ich versucht, mit nur mpirun Option

mpirun -CPU-Set 144-191 -np 64 ./myexec param> logfile.log

aber die -CPU-Set-Option ist nicht massiv dokumentiert, und ich finde keine Möglichkeit, einen Prozess pro Kern zu binden.

Die Frage: Kann jemand mir helfen, einen Prozess pro Kern zu haben, auf den Kernen, die ich will?

Antwort

2

336-383 aus der Liste der physischen CPUs im Befehl numactl ausschließen. Dies sind die zweiten Hardware-Threads, und wenn sie in der Liste der zulässigen CPUs enthalten sind, kann das Betriebssystem zwei Prozesse auf den verschiedenen Hardware-Threads desselben Kerns planen.

Allgemeinen bei Open MPI, Mapping und Bindung sind zwei getrennte Vorgänge und die beide auf Kernbasen zu erledigen, sind folgende Optionen erforderlich:

--map-by core --bind-to core 

Der Mapper startet standardmäßig aus dem ersten Kern auf die erste Steckdose. Um die Kernauswahl zu begrenzen, übergeben Sie die --cpu-set from-to. In Ihrem Fall sollte der vollständige Befehl sein:

mpirun --cpu-set 144-191 --map-by core --bind-to core -np 64 ./myexec param > logfile.log 

Sie auch die Option --report-bindings passieren kann eine schöne grafische Visualisierung der Bindung zu erhalten (die in Ihrem Fall wird ein bisschen schwer zu lesen ...)

Beachten Sie, dass --nooversubscribe verwendet wird, um zu verhindern, dass die Bibliothek mehr Prozesse platziert, als auf dem Knoten definierte Steckplätze vorhanden sind. Standardmäßig gibt es so viele Slots wie logische CPUs, die vom Betriebssystem erkannt werden. Daher führt die Übergabe dieser Option in Ihrem Fall nicht dazu (64 < 384).

+0

- rechts für die Threads kann jeder Kern 2 Threads haben (alle Core über 191 sind die 'virtuellen' Threads). Ist mein Fall, ich will 64 Prozesse, über 12cores cpus, so brauche ich 5,3 cpus. Um die Kommunikationskosten zu reduzieren, habe ich überlegt, nur 4cpus zu verwenden, also 48cores und die restlichen 16 auf die virtuellen. ist es möglich? zusätzliche Fragen/rate: - von htop kann ich sehen, dass meine Prozesse zwischen den beiden Threads des Kerns, an den es gebunden ist (168 bis 360 zum Beispiel) springen? Es ist normal? - Kann ich numactl -l in der Befehlszeile hinzufügen, um den Speicher lokal zu machen? Oder ist es weniger? –

+1

Ja, wenn Sie die Ausgabe ansehen, wenn '--report-bindings' aktiv ist, sehen Sie etwas wie' ../ BB /../ .. ', was bedeutet, dass die Prozesse an beide Hardware-Threads gebunden sind . Die Migration zwischen ihnen ist sehr kostengünstig, da sich Hardware-Threads die gesamte Cache-Hierarchie teilen. Sie können "--bind-to hwthread" verwenden, um nur an einen einzelnen Thread zu binden, aber das könnte den Mapper verwirren, wenn er in Kombination mit '--cpu-set' verwendet wird (zumindest auf meinem System). –

+0

Speicherbindung, Open MPI führt eine gewisse Speicherbindung durch, wenn die CPU-Bindung aktiviert wird. Aber wenn Sie möchten, dass Sie sicher und spezifisch sein, können Sie Ihr Programm mit 'numactl -m' wickeln, zB' mpirun ... -n 12 numactl -m 10 ./myexec param: -n 12 numactl -m 11 ./myexec param: -n 12 numactl -m 12 ./myexec param'. Dies wird 3 Gruppen von 12 Prozessen starten, deren Speicher an Knoten 10, 11 bzw. 12 gebunden ist. Die Prozesse werden immer noch Teil desselben MPI-Jobs sein, d. H. Teilen sich "MPI_COMM_WORLD". Stellen Sie sicher, dass die NUMA-Knoten mit denen übereinstimmen, auf denen jeder Prozess ausgeführt wird. –