Paralleljs: Elegante Web Worker -Lösung
paralleljs bietet eine elegante Lösung für die Probleme, die bei der Verwendung von Web Worker auftreten können, und bietet eine praktische API mit bequemer Abstraktions- und Helfer -Tools. Die von HTML5 eingeführte Worker -Schnittstelle ermöglicht die Erstellung von Funktionen mit langfristiger Zeit und hohen Rechenanforderungen, die gleichzeitig verwendet werden können, um die Reaktionsgeschwindigkeit der Website zu verbessern. Paralleljs ermöglicht eine Parallelisierung des JavaScript -Codes und nutzt gleichzeitig Multithreading (SMT), um moderne CPUs effizienter zu verwenden. Die Paralleljs -Bibliothek enthält Methoden wie spawn
, map
und reduce
, die zur Durchführung von Berechnungen, Prozessdaten und aggregierten Fragmentierungsergebnissen verwendet werden.
Eine der coolsten neuen Möglichkeiten, die von HTML5 eingeführt wurden, ist die Arbeiteroberfläche der Web Workers API. Zuvor mussten wir einige Tipps übernehmen, um den Benutzern eine reaktionsschnelle Website zu zeigen. Mit der Worker -Schnittstelle können wir Funktionen mit langfristigen und hohen Rechenanforderungen erstellen. Darüber hinaus können Arbeiterinstanzen gleichzeitig verwendet werden, sodass wir bei Bedarf eine beliebige Anzahl dieser Arbeitnehmer generieren können. In diesem Artikel werde ich diskutieren, warum Multithreading wichtig ist und wie es mit Paralleljs in JavaScript implementiert werden kann.
Warum brauchen Sie Multi-Threading?
Dies ist eine vernünftige Frage. In der Vergangenheit bietet die Fähigkeit, Fäden zu generieren, eine elegante Möglichkeit, die Arbeit in einem Prozess zu teilen. Das Betriebssystem ist für die Planung der verfügbaren Zeit für jeden Thread verantwortlich, so dass Threads mit höherer Priorität und höherer Workloads Vorrang vor Prioritäts -Leerlauf -Threads haben. In den letzten Jahren ist das gleichzeitige Multithreading (SMT) zum Schlüssel zum Zugriff auf moderne CPU -Rechenleistung geworden. Der Grund ist einfach: Das Gesetz von Moore ist in Bezug auf die Anzahl der Transistoren pro Flächeneinheit weiterhin gültig. Die Frequenzskalierung muss jedoch aus verschiedenen Gründen gestoppt werden. Daher müssen verfügbare Transistoren auf andere Weise verwendet werden. Es wird beschlossen, dass architektonische Verbesserungen (wie SIMD) und Multi-Core die beste Wahl darstellen.
Um SMT zu verwenden, müssen wir parallelen Code schreiben, dh Code, der parallel ausgeführt wird, um ein einzelnes Ergebnis zu erhalten. Normalerweise müssen wir spezielle Algorithmen berücksichtigen, da die meisten sequentiellen Codes entweder schwer parallelisieren oder sehr ineffizient sind. Der Grund ist das Amdahlsche Gesetz, das besagt, dass die Beschleunigungsverhältnis s durch die folgende Formel angegeben ist:
wobei n die Anzahl der parallelen Arbeiter (wie Prozessor, Kern oder Thread) und p ist der parallele Teil. In Zukunft können mehr Multi-Kern-Architekturen verwendet werden, die sich auf parallele Algorithmen stützen. Im Bereich Hochleistungs-Computing repräsentieren GPU-Systeme und spezielle Architekturen wie Intel Xeon PHI solche Plattformen. Schließlich sollten wir zwischen allgemeinen gleichzeitigen Anwendungen oder Algorithmen und parallelen Ausführung unterscheiden. Parallelität ist die (möglicherweise relevante) gleichzeitige Ausführung der Berechnung. Umgekehrt ist Parallelität eine Kombination unabhängiger Ausführungsprozesse.
Multi-Threading in JavaScript
In JavaScript wissen wir bereits, wie man gleichzeitige Programme schreibt, d. H. Mithilfe von Callback -Funktionen. Dieses Wissen kann jetzt auf die Schaffung eines parallelen Programms übertragen werden! Nach seiner eigenen Struktur wird JavaScript in einem einzigen Thread ausgeführt, das durch eine Ereignisschleife vermittelt wird (normalerweise nach Reaktormuster). Dies bietet uns beispielsweise eine gute Abstraktion für uns, um asynchrone Anforderungen an (externe) Ressourcen zu bearbeiten. Es stellt auch sicher, dass zuvor definierte Rückrufe immer in denselben Ausführungs -Thread abgefeuert werden. Es gibt keine Cross-Thread-Ausnahmen, Rassenbedingungen oder andere Probleme im Zusammenhang mit Threads. Dies bringt uns jedoch nicht näher an SMT in JavaScript. Mit der Einführung von Arbeiteroberflächen wurde eine elegante Lösung gefunden. Aus Sicht der Hauptanwendung sollte der Code in Web Worker als Aufgabe betrachtet werden, die gleichzeitig ausgeführt wird. Auf diese Weise wird auch Kommunikation durchgeführt. Wir verwenden die Nachrichten -API, die auch für die Kommunikation von enthaltenen Websites zu gehosteten Seiten verwendet werden kann. Beispielsweise antwortet der folgende Code auf eingehende Nachrichten, indem er eine Nachricht an den Initiator sendet.
window.addEventListener('message', function (event) { event.source.postMessage('Howdy Cowboy!', event.origin); }, false);
theoretisch kann ein Webarbeiter auch einen anderen Webarbeiter generieren. Tatsächlich verbieten die meisten Browser dies jedoch. Daher ist die einzige Möglichkeit, zwischen Web Workers zu kommunizieren, über die Hauptanwendung. Kommunikation durch Nachrichten werden gleichzeitig durchgeführt, sodass nur asynchrone (nicht blockierende) Kommunikation durchgeführt wird. Zuerst mag dies in der Programmierung seltsam sein, aber es bringt viele Vorteile. Am wichtigsten ist, dass unser Code keine Rennbedingungen haben sollte! Schauen wir uns ein einfaches Beispiel für die Verwendung von zwei Parametern an, um den Start und Ende der Sequenz darzustellen, um eine Folge von Primzahlen im Hintergrund zu berechnen. Zunächst erstellen wir eine Datei namens Prime.js mit dem folgenden Inhalt:
onmessage = function (event) { var arguments = JSON.parse(event.data); run(arguments.start, arguments.end); }; function run (start, end) { var n = start; while (n < end) { var k = Math.sqrt(n); var found = false; for (var i = 2; !found && i <= k; i++) { found = n % i === 0; } if (!found) { postMessage(n.toString()); } n++; } }
Jetzt müssen wir nur den folgenden Code in der Hauptanwendung verwenden, um den Hintergrundarbeiter zu starten.
if (typeof Worker !== 'undefined') { var w = new Worker('prime.js'); w.onmessage = function(event) { console.log(event); }; var args = { start : 100, end : 10000 }; w.postMessage(JSON.stringify(args)); }
ziemlich viel Arbeit. Besonders ärgerlich ist es, eine andere Datei zu verwenden. Dies erzeugt eine schöne Trennung, scheint aber für kleinere Aufgaben völlig überflüssig zu sein. Glücklicherweise gibt es eine Lösung. Betrachten Sie den folgenden Code:
var fs = (function () { /* code for the worker */ }).toString(); var blob = new Blob( [fs.substr(13, fs.length - 14)], { type: 'text/javascript' } ); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); // Now setup communication and rest as before
Natürlich möchten wir vielleicht eine bessere Lösung als solche magischen Zahlen (13 und 14) haben, und abhängig vom Browser muss der Fallback des Blob und CreateObjecturl verwendet werden. Wenn Sie kein JavaScript -Experte sind, soll Fs.Substr (13, Fs.Length - 14) den Funktionskörper extrahieren. Wir tun dies, indem wir die Funktionserklärung in eine Zeichenfolge konvertieren (mit toString () genannt) und die Signatur der Funktion selbst entfernen.
Können Paralleljs helfen?
Hier kommt Paralleljs ins Spiel. Es bietet eine nette API für Komfort sowie Webarbeiter. Es enthält viele Hilfswerkzeuge und sehr nützliche Abstraktionen. Wir stellen zunächst einige Daten zur Verfügung.
var p = new Parallel([1, 2, 3, 4, 5]); console.log(p.data);
Daten erzeugt das bereitgestellte Array. Es wurden noch keine "parallele" Operationen einberufen. Instanz P enthält jedoch eine Reihe von Methoden wie Spawn, die einen neuen Webarbeiter erstellen. Es gibt ein Versprechen zurück, was die Verwendung der Ergebnisse zu einem Kinderspiel macht.
window.addEventListener('message', function (event) { event.source.postMessage('Howdy Cowboy!', event.origin); }, false);
Das Problem mit dem obigen Code ist, dass die Berechnungen nicht wirklich parallel sind. Wir erstellen nur einen einzelnen Hintergrundarbeiter, der das gesamte Datenarray gleichzeitig verarbeitet. Erst nach der Bearbeitung des gesamten Arrays können wir das Ergebnis erhalten. Eine bessere Lösung besteht darin, die Kartenfunktion der parallelen Instanz zu verwenden.
onmessage = function (event) { var arguments = JSON.parse(event.data); run(arguments.start, arguments.end); }; function run (start, end) { var n = start; while (n < end) { var k = Math.sqrt(n); var found = false; for (var i = 2; !found && i <= k; i++) { found = n % i === 0; } if (!found) { postMessage(n.toString()); } n++; } }
Im vorherigen Beispiel ist der Kern sehr einfach und kann zu einfach sein. In einem wirklichen Beispiel werden viele Operationen und Funktionen beteiligt sein. Wir können die erforderliche Funktion verwenden, um die importierten Funktionen einzuschließen.
if (typeof Worker !== 'undefined') { var w = new Worker('prime.js'); w.onmessage = function(event) { console.log(event); }; var args = { start : 100, end : 10000 }; w.postMessage(JSON.stringify(args)); }
Reduzierung der Funktion hilft, fragmentierte Ergebnisse zu einem einzigen Ergebnis zu aggregieren. Es bietet eine bequeme Abstraktion für das Sammeln von Unterreulten und die Durchführung bestimmter Operationen, nachdem Sie alle Unterreulte kennen.
Schlussfolgerung
Paralleljs bietet uns eine elegante Möglichkeit, Probleme zu vermeiden, die bei der Verwendung von Web Worker auftreten können. Darüber hinaus erhalten wir eine schöne API mit einigen nützlichen Abstraktionen und Helfern. Weitere Verbesserungen können in Zukunft integriert werden. Neben der Möglichkeit, SMT in JavaScript zu verwenden, möchten wir möglicherweise auch die Vektorisierung verwenden. Bei der Unterstützung scheint Simd.js ein praktikabler Ansatz zu sein. In einigen (hoffentlich nicht zu weit entfernten) Futures kann die Verwendung von GPUs für die Berechnung auch eine gültige Option sein. Es gibt einen Wrapper für CUDA (eine parallele Computerarchitektur) in Node.js, aber der ursprüngliche JavaScript -Code ist immer noch nicht möglich. Bis dahin war Paralleljs die beste Wahl, um Multi-Core-CPUs zu nutzen, um das langjährige Computer zu bewältigen. Und du? Wie verwenden Sie JavaScript, um die Kraft der modernen Hardware zu entfesseln?
FAQs (FAQ) auf Paralleljs mit Paralleljs
Paralleljs ist eine JavaScript-Bibliothek, mit der Sie die Datenverarbeitung parallelisieren können, indem Sie Multi-Core-Prozessoren nutzen. Es funktioniert, indem es ein neues paralleles Objekt erstellt und eine Reihe von Daten an sie weitergibt. Diese Daten können dann parallel unter Verwendung der .map()
-Methode verarbeitet werden, die die angegebene Funktion auf jedes Element im Array anwendet. Geben Sie dann das Ergebnis im Neuarray zurück.
Paralleljs können mit NPM (Node.js Package Manager) installiert werden. Führen Sie einfach den Befehl "NPM installieren paralleljs" im Terminal aus. Sobald die Installation abgeschlossen ist, können Sie sie in Ihrer JavaScript -Datei mit "var parallel = Request ('paralleljs') verweisen;".
Paralleljs können Sie Ihre Datenverarbeitungsaufgaben mit Multi-Core-Prozessoren optimal nutzen. Dies kann die Verarbeitungszeit bei großen Datensätzen erheblich beschleunigen. Es bietet auch eine einfache und intuitive API, die den Parallelisierungscode erleichtert.
Ja, Paralleljs können im Browser verwendet werden. Sie können es mit dem Skript -Tag und der URL der Paralleljs -Datei in die HTML -Datei aufnehmen. Sobald Sie eingeschlossen sind, können Sie das parallele Objekt genau wie in Node.js. verwenden.
.map()
-Methode in Paralleljs verwenden? Die .map()
-Methode in Paralleljs wird verwendet, um eine Funktion auf jedes Element in einem Datenarray anzuwenden. Diese Funktion wird als Zeichenfolge an die .map()
-Methode übergeben. Geben Sie dann das Ergebnis im Neuarray zurück. Zum Beispiel "var p = neuer Parallel ([1, 2, 3]); p.map ('Funktion (n) {return n * 2;}'); ] Neue Array.
.reduce()
-Methode für Paralleljs? Die .reduce()
-Methode in Paralleljs wird verwendet, um das Datenarray unter Verwendung der angegebenen Funktion auf einen einzelnen Wert zu reduzieren. Diese Funktion wird als Zeichenfolge an die .reduce()
-Methode übergeben. Zum Beispiel "var p = neuer Parallel ([1, 2, 3]); P.Reduce ('Funktion (a, b) {return a b;}');
Ja, Methoden paralleljs können miteinander verknüpft werden. Beispielsweise können Sie die .map()
-Methode verwenden, um die Daten zu verarbeiten und dann mit der Methode .reduce()
die Ergebnisse zu einem einzelnen Wert zu kombinieren.
Die Fehler in Paralleljs können mit der Methode .catch()
behandelt werden. Diese Methode akzeptiert eine Funktion, die aufgerufen wird, wenn während der Verarbeitung ein Fehler auftritt. Das Fehlerobjekt wird an diese Funktion übergeben.
Ja, Paralleljs können mit anderen JavaScript -Bibliotheken verwendet werden. Sie müssen jedoch sicherstellen, dass die Bibliothek mithilfe der .require()
-Methode die Bibliothek in den Arbeiterkontext einbezieht.
Während Paralleljs die Verarbeitungszeit in großen Datensätzen erheblich beschleunigen können, ist dies möglicherweise nicht die beste Wahl für alle Aufgaben. Für kleine Datensätze kann der Aufwand des Erstellens von Arbeitnehmern und Übertragung von Daten die Vorteile der Parallelisierung überwiegen. Es ist besser, Paralleljs mit Ihrem speziellen Anwendungsfall zu testen, um festzustellen, ob es Leistungsvorteile bietet.
Das obige ist der detaillierte Inhalt vonParallele JavaScript mit Paralleljs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!