2016-04-24 2 views
3

Ich bin neu in Elixir, und ich beginne zu lesen Dave Thomas hervorragende Programmierung Elixir. Ich war neugierig, wie weit ich die Parallelität der "pmap" -Funktion nutzen konnte, also erhöhte ich die Anzahl der Elemente iterativ von 1.000 auf 10.000.000. Aus Neugier, ich die Ausgabe von htop beobachtete, wie ich so tat, in der Regel mit CPU-Auslastung ähnlich wie unten gezeigt Peaking aus:Wie bekomme ich die simultane Funktion (pmap) um alle Kerne in Elixir zu verwenden?

htop output

im Buch Nach zeigt das Beispiel, Dave sagt:

Und ja, ich habe gerade 1000 Hintergrundprozesse gestartet, und ich habe alle Kerne und Prozessoren auf meinem Rechner verwendet.

Meine Frage ist, wie kommt auf meiner Maschine nur die Kerne 1, 3, 5 und 7 leuchten? Meine Vermutung ist, dass es mit meinem iex Prozess nur einen einzigen Prozess auf Betriebssystemebene zu tun hat und OSX verwaltet die Reichweite dieses Prozesses. Geht das hier? Gibt es eine Möglichkeit sicherzustellen, dass alle Kerne für leistungsintensive Aufgaben verwendet werden?

+0

Was ist die erste Ausgabezeile von iex? zB: "Erlang/OTP 18 [erts-7.3] [Quelle] [64-Bit] [smp: 4: 4] [async-threads: 10] [hipe] [kernel-poll: false] [dtrace]" –

+0

@ ThiagoSilveira'Erlang/OTP 18 [erts-7.3] [Quelle] [64-bit] [smp: 8: 8] [async-threads: 10] [hipe] [kernel-poll: false] [dtrace] ' – user456584

Antwort

8

Großartiger Kommentar von @Thiago Silveira über die erste Ausgabe des iex. Der Teil [smp:8:8] sagt aus, wie viele Prozesse auf Betriebssystemebene Erlang verwendet. Sie können dies mit Flagge steuern --smp, wenn Sie es deaktivieren möchten:

iex --erl '-smp disable' 

Dadurch wird sichergestellt, dass Sie nur ein Systemprozess haben. Sie können ein ähnliches Ergebnis erzielen, indem Sie die symmetrische Mehrfachverarbeitung aktiviert lassen, aber direkt NumberOfShcedulers:NumberOfSchedulersOnline setzen.

iex --erl '+S 1:1' 

Jedes Betriebssystem Prozess benötigt einen eigenen Scheduler für Erlang Prozesse haben, so können Sie leicht sehen, wie viele von ihnen haben Sie zur Zeit:

:erlang.system_info(:schedulers_online) 

Ihre Frage über die Leistung zu beantworten. Wenn Ihre Prozessoren nicht mit voller Kapazität arbeiten (100%) und keiner von ihnen nichts tut (0%), ist es wahrscheinlich, dass die Last nicht gleichmäßiger verteilt wird, wenn sie gleichmäßiger verteilt wird. Warum?

Die CPU-Auslastung wird gemessen, indem der Prozessorstatus zu vielen Zeitpunkten untersucht wird. Diese Zustände sind entweder "Arbeiten" oder "Leerlauf". Eine CPU-Auslastung von 82% bedeutet, dass Sie mehrere Aufgaben auf dieser CPU ausführen können, ohne andere Aufgaben zu verlangsamen.

Erlang-Scheduler versuchen, intelligent zu sein und Erlang-Prozesse zwischen Kernen nicht zu migrieren, es sei denn, sie müssen es, weil sie kopiert werden müssen. Die Migration findet beispielsweise statt, wenn einer der Scheduler im Leerlauf ist. Es kann dann einen Prozess von anderen Scheduler-Run-Queue ausleihen.

Das nächste, was solch eine große Diskrepanz zwischen ungeraden und geraden Kernen verursachen kann, ist Hyper Threading. Auf meinem Dual-Core-Prozessor htop zeigt 4 logische Kerne. In Ihrem Fall haben Sie wahrscheinlich 4 physische Kerne und 8 logische wegen HT. Es kann der Fall sein, dass Sie Ihre physischen Kerne mit 100% verwenden.

Eine andere Sache: pmap muss Ergebnis in separaten Prozess berechnen, aber am Ende sendet es an den Anrufer, die ein Engpass sein kann. Je mehr Nachrichten gesendet werden, desto weniger CPU-Auslastung können Sie erzielen. Sie können versuchen, den Prozessen eine Aufgabe zu geben, die wirklich CPU-intensiv ist, wie die Berechnung Ackerman function.Mit Amdahl's law können Sie sogar berechnen, wie viel von Ihrem Job der sequentielle Teil und wie viel parallel ist, und die Ausführungszeiten für verschiedene Kerne messen.

Zusammenfassend: die CPU-Auslastung von Screenshot sieht wirklich toll aus! Für leistungsintensivere Aufgaben müssen Sie nichts ändern.

+1

Sehr aufschlussreich Antwort - Danke! – user456584

2

Concurrency ist nicht Parallelism

Um aus Elixir/BEAM gute parallele Leistung zu erhalten Codierung Sie ein gewisses Verständnis dafür, wie die BEAM-Scheduler funktioniert haben müssen.

Dies ist ein sehr vereinfachtes Modell, aber der BEAM-Scheduler gibt jedem Prozess 2000 Reduktionen, bevor er den Prozess für den nächsten Prozess austauscht. Reduktionen können als Funktionsaufrufe betrachtet werden. Standardmäßig wird ein Prozess auf dem Core/Scheduler ausgeführt, der ihn erstellt hat. Prozesse werden nur dann zwischen Schedulern verschoben, wenn sich die Warteschlange ausstehender Prozesse in einem bestimmten Scheduler aufbaut. Standardmäßig führt der BEAM einen Planungsthread für jeden verfügbaren Kern aus.

Das bedeutet, dass Sie, um die Prozessoren bestmöglich zu nutzen, Ihre Aufgaben in ausreichend große Arbeitsaufgaben aufteilen müssen, die den Standardarbeitsbereich "Reduktion" überschreiten. Im Allgemeinen gibt die Pmap-Stil-Parallelität nur dann signifikante Beschleunigung, wenn Sie viele Elemente in eine einzelne Aufgabe aufteilen.

Die andere Sache bewusst zu sein, dass einige Teile des BEAM einen Spin verwenden/Schleife warten, wenn die Arbeit wartet, und das kann Nutzung schief, wenn Sie ein Tool wie htop verwenden CPU-Auslastung zu untersuchen. Mit :observer können Sie die Leistung Ihres Programms besser verstehen.

Verwandte Themen