Erlangs Eigenschaften
Aus der Erlang-Programmierung (2009):
Die Erlang-Parallelität ist schnell und skalierbar. Die Prozesse sind insofern leichtgewichtig, als die virtuelle Erlang-Maschine nicht für jeden erstellten Prozess einen Betriebssystem-Thread erstellt. Sie werden in der VM unabhängig vom zugrunde liegenden Betriebssystem erstellt, geplant und verarbeitet. Infolgedessen liegt die Prozesserstellungszeit in der Größenordnung von Mikrosekunden und unabhängig von der Anzahl der gleichzeitig vorhandenen Prozesse. Vergleichen Sie dies mit Java und C #, wo für jeden Prozess ein zugrunde liegender Betriebssystem-Thread erstellt wird: Sie erhalten einige sehr wettbewerbsfähige Vergleiche, wobei Erlang beide Sprachen deutlich übertrifft.
Aus der Parallelitätsorientierten Programmierung in Erlang (pdf) (Folien) (2003):
Wir stellen fest, dass die für die Erstellung eines Erlang-Prozesses benötigte Zeit konstant 1µs bis zu 2.500 Prozessen beträgt. danach steigt sie für bis zu 30.000 Prozesse auf etwa 3 us an. Die Leistung von Java und C # ist oben in der Abbildung dargestellt. Für eine kleine Anzahl von Prozessen dauert es ungefähr 300 us, um einen Prozess zu erstellen. Es ist unmöglich, mehr als zweitausend Prozesse zu erstellen.
Wir sehen, dass für bis zu 30.000 Prozesse die Zeit zum Senden einer Nachricht zwischen zwei Erlang-Prozessen etwa 0,8 µs beträgt. Für C # dauert es ungefähr 50µs pro Nachricht, bis zur maximalen Anzahl von Prozessen (die ungefähr 1800 Prozesse waren). Java war noch schlimmer, für bis zu 100 Prozesse dauerte es ungefähr 50 us pro Nachricht, danach stieg es schnell auf 10 ms pro Nachricht an, wenn es ungefähr 1000 Java-Prozesse gab.
Meine Gedanken
Ich verstehe technisch nicht ganz, warum Erlang-Prozesse beim Laichen neuer Prozesse so viel effizienter sind und viel weniger Speicherbedarf pro Prozess haben. Sowohl das Betriebssystem als auch die Erlang-VM müssen die Planung und den Kontextwechsel durchführen und die Werte in den Registern usw. verfolgen.
Warum werden Betriebssystem-Threads nicht wie Prozesse in Erlang implementiert? Müssen sie etwas mehr unterstützen? Und warum benötigen sie einen größeren Speicherbedarf? Und warum haben sie langsameres Laichen und Kommunikation?
Warum sind Prozesse in Erlang technisch gesehen effizienter als OS-Threads, wenn es um das Laichen und die Kommunikation geht? Und warum können Threads im Betriebssystem nicht auf dieselbe effiziente Weise implementiert und verwaltet werden? Und warum haben Betriebssystem-Threads einen größeren Speicherbedarf sowie ein langsameres Laichen und eine langsamere Kommunikation?
erl +P 1000100 +hms 100
und als Typ{_, PIDs} = timer:tc(lists,map,[fun(_)->spawn(fun()->receive stop -> ok end end) end, lists:seq(1,1000000)]).
und als Wartezeit etwa drei Minuten für Ergebnis. Das ist so einfach. Es dauert 140us pro Prozess und 1 GB RAM auf meinem Laptop. Aber es ist direkt von der Shell, es sollte besser aus kompiliertem Code sein.Antworten:
Es gibt mehrere Faktoren, die dazu beitragen:
quelle
Nach einigen weiteren Recherchen fand ich eine Präsentation von Joe Armstrong.
Aus Erlang - Software für eine gleichzeitige Welt (Präsentation) (um 13 min):
Ich denke, es beantwortet, wenn nicht alle, zumindest einige meiner Fragen
quelle
Ich habe Coroutinen in Assembler implementiert und die Leistung gemessen.
Das Umschalten zwischen Coroutinen, auch Erlang-Prozessen genannt, benötigt auf einem modernen Prozessor etwa 16 Anweisungen und 20 Nanosekunden. Außerdem kennen Sie häufig den Prozess, zu dem Sie wechseln (Beispiel: Ein Prozess, der eine Nachricht in seiner Warteschlange empfängt, kann als direkte Übergabe vom aufrufenden Prozess an den empfangenden Prozess implementiert werden), damit der Scheduler nicht ins Spiel kommt es ist eine O (1) -Operation.
Das Wechseln von Betriebssystem-Threads dauert etwa 500 bis 1000 Nanosekunden, da Sie den Kernel aufrufen. Der OS-Thread-Scheduler wird möglicherweise in der Zeit O (log (n)) oder O (log (log (n))) ausgeführt. Dies macht sich bemerkbar, wenn Sie Zehntausende oder sogar Millionen von Threads haben.
Daher sind Erlang-Prozesse schneller und skalieren besser, da sowohl die grundlegende Umschaltoperation schneller ist als auch der Scheduler weniger häufig ausgeführt wird.
quelle
Erlang-Prozesse entsprechen (ungefähr) grünen Fäden in anderen Sprachen; Es gibt keine vom Betriebssystem erzwungene Trennung zwischen den Prozessen. (Es mag durchaus eine sprachgesteuerte Trennung geben, aber das ist ein geringerer Schutz, obwohl Erlang einen besseren Job macht als die meisten anderen.) Weil sie so viel leichter sind, können sie weitaus umfangreicher verwendet werden.
OS-Threads hingegen können einfach auf verschiedenen CPU-Kernen geplant werden und (meistens) unabhängige CPU-gebundene Verarbeitung unterstützen. Betriebssystemprozesse sind wie Betriebssystemthreads, jedoch mit einer viel stärkeren vom Betriebssystem erzwungenen Trennung. Der Preis für diese Funktionen ist, dass Betriebssystem-Threads und (noch mehr) Prozesse teurer sind.
Ein anderer Weg, um den Unterschied zu verstehen, ist dieser. Angenommen, Sie würden eine Implementierung von Erlang über die JVM schreiben (kein besonders verrückter Vorschlag), dann würden Sie jeden Erlang-Prozess zu einem Objekt mit einem bestimmten Status machen. Sie hätten dann einen Pool von Thread-Instanzen (normalerweise entsprechend der Anzahl der Kerne in Ihrem Host-System; dies ist ein einstellbarer Parameter in echten Erlang-Laufzeiten übrigens), die die Erlang-Prozesse ausführen. Dadurch wird die zu erledigende Arbeit auf die tatsächlich verfügbaren Systemressourcen verteilt. Es ist eine ziemlich nette Art, Dinge zu tun, aber es hängt absolut davon abauf die Tatsache, dass jeder einzelne Erlang-Prozess nicht viel bewirkt. Das ist natürlich in Ordnung; Erlang ist so strukturiert, dass diese einzelnen Prozesse nicht schwergewichtig sein müssen, da das gesamte Ensemble von ihnen das Programm ausführt.
In vielerlei Hinsicht ist das eigentliche Problem die Terminologie. Die Dinge, die Erlang Prozesse nennt (und die in CSP, CCS und insbesondere im π-Kalkül stark dem gleichen Konzept entsprechen), sind einfach nicht die gleichen wie die Dinge, die Sprachen mit einem C-Erbe (einschließlich C ++, Java, C # und viele andere) rufen einen Prozess oder einen Thread auf. Es gibt einige Ähnlichkeiten (alle beinhalten eine Vorstellung von gleichzeitiger Ausführung), aber es gibt definitiv keine Äquivalenz. Seien Sie also vorsichtig, wenn jemand zu Ihnen „Prozess“ sagt. sie könnten verstehen, dass es etwas völlig anderes bedeutet ...
quelle
Ich denke, Jonas wollte einige Zahlen zum Vergleich von Betriebssystem-Threads mit Erlang-Prozessen. Der Autor von Programming Erlang, Joe Armstrong, hat vor einiger Zeit die Skalierbarkeit des Laichens von Erlang-Prozessen auf Betriebssystem-Threads getestet. Er schrieb einen einfachen Webserver in Erlang und testete ihn gegen Apache mit mehreren Threads (da Apache Betriebssystem-Threads verwendet). Es gibt eine alte Website mit Daten aus dem Jahr 1998. Ich habe es nur geschafft, diese Website genau einmal zu finden. Ich kann also keinen Link angeben. Aber die Informationen sind da draußen. Der Hauptpunkt der Studie zeigte, dass Apache knapp 8K-Prozesse maximal ausnutzte, während sein handgeschriebener Erlang-Server mehr als 10K-Prozesse abwickelte.
quelle
Da sich der Erlang-Interpreter nur um sich selbst kümmern muss, muss sich das Betriebssystem um viele andere Dinge kümmern.
quelle
Einer der Gründe dafür ist, dass der erlang-Prozess nicht im Betriebssystem, sondern in der evm (erlang virtual machine) erstellt wird, sodass die Kosten geringer sind.
quelle