1 Punkte von GN⁺ 3 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • Ab Firefox 148 ist die asm.js-Optimierung von SpiderMonkey standardmäßig deaktiviert, und der zugehörige Code soll in künftigen Releases entfernt werden
  • asm.js ist eine Teilmenge von JavaScript, daher funktionieren bestehende Websites weiterhin, laufen aber über den normalen JIT-Pfad, wodurch die Optimierungsvorteile entfallen
  • Wenn asm.js-Inhalte zu WebAssembly neu kompiliert werden, sind schnellere Ausführung und kleinere Binärdateien möglich
  • Gegenüber NaCl·PNaCl machte asm.js eine nahezu native Ausführung innerhalb von Web-Inhalten möglich, ganz ohne separate Sandbox oder alternative APIs
  • OdinMonkey, eingeführt 2013 in Firefox 22, ermöglichte Web-Deployments von C/C++-Projekten wie Unity und Unreal und legte die Grundlage für WebAssembly

Deaktivierung der asm.js-Optimierung

  • Seit Firefox 148 ist die asm.js-Optimierung von SpiderMonkey standardmäßig deaktiviert, und in einer kommenden Version soll der gesamte zugehörige Code entfernt werden
  • Websites, die asm.js verwenden, funktionieren weiterhin
    • asm.js ist eine Teilmenge von normalem JavaScript, daher wird bestehender Code wie andere Skripte über den normalen JIT-Pfad ausgeführt
    • Allerdings entfallen die Vorteile der asm.js-spezifischen Optimierung
  • Wenn weiterhin asm.js-Inhalte ausgeliefert werden, wird empfohlen, sie zu WebAssembly neu zu kompilieren
    • Durch eine Neukompilierung zu WebAssembly sind schnellere Ausführung und kleinere Binärdateien möglich
    • Die WebAssembly-Pipeline von SpiderMonkey ist deutlich weiter entwickelt als die asm.js-Pipeline
  • Da WebAssembly erfolgreich ist und der Großteil der asm.js-Nutzung bereits migriert wurde, steigen die Kosten, beide Pfade parallel zu pflegen
    • Es ist weiterhin Wartungsaufwand nötig
    • Im VM bleibt zusätzliche Angriffsfläche bestehen

Die Rolle von asm.js und das Ende von OdinMonkey

  • asm.js war Mozillas Antwort auf die von NaCl und PNaCl aufgeworfene Frage: „Kann Code im Web mit nativer Geschwindigkeit ausgeführt werden?“
    • Dafür wurde eine strikte, statisch typisierte Teilmenge von JavaScript gewählt, die die Engine sofort erkennen und zu nativem Code kompilieren konnte
    • So blieb alles innerhalb von Web-Inhalten, ohne separate Sandbox, IPC oder alternative APIs, und vorhandene Web-APIs konnten weiter genutzt werden
  • asm.js wurde 2013 in Firefox 22 aufgenommen und ermöglichte Projekten wie Unity und Unreal, C/C++-Codebasen ausschließlich mit standardisierten Web-Technologien ins Web zu bringen
  • Der asm.js-Compiler hieß OdinMonkey, und seine Entfernung wird im Ragnarök-Bug unter dem Titel „Twilight of OdinMonkey“ verfolgt
    • BaldrMonkey, hervorgegangen aus OdinMonkey, ist der optimierende Compiler für WebAssembly
    • RabaldrMonkey ist der Baseline-Compiler für WebAssembly
    • Nach 13 Jahren geht OdinMonkey nun seinem Ende entgegen

1 Kommentare

 
GN⁺ 3 시간 전
Hacker-News-Kommentare
  • asm.js war Mozillas Antwort auf die von NaCl und PNaCl aufgeworfene Frage: „Wie führt man Code im Web mit nativer Geschwindigkeit aus?“
    Wenn das heute passieren würde, hätte Chrome NaCl und PNaCl wohl einfach durchgedrückt, und dann hätten sich alle darüber beschwert, warum Safari und Firefox den „Web“-Standards nicht folgen

    • Ich denke immer noch, dass wir in der falschen Zeitlinie leben. PNaCl ist tot, und statt eines würdigen Nachfolgers, der rechtzeitig erschienen wäre, werden wir lebendig in einer Suppe aus Electron-Apps gekocht.
      Eine Zeit lang dachte ich ernsthaft, wir würden alles im Browser erledigen. In gewisser Weise entwickelt es sich auch in diese Richtung, aber das Gesamterlebnis fühlt sich schlechter an als je zuvor. Ich mag WASM und möchte es mögen, aber wie langsam das Ökosystem reift, ist kaum zu glauben.
      Noch schlimmer ist, dass wir unzuverlässige AI-Tools und ihre Ausgaben genau in so einer Sandbox ausführen müssten, während Unternehmen stattdessen gehostete Sandboxes und gehostete JS-basierte VMs verkaufen.
      Am Ende war es wohl immer dasselbe Problem. Mit clientseitigen Sandboxes ließ sich kein Geld verdienen
    • Soweit ich mich erinnere, war das nicht so. Damals war es ein nützliches Experiment, aber am Ende hat es nicht funktioniert.
      Intern war es nützlich, um den Flash-Player zu sandboxen, aber die Grenzen des LLVM-basierten Ansatzes wurden bald allen Beteiligten klar
    • Tatsächlich wollten sie im Grunde genau das damals auch tun. Sie versuchten, es über die Web-Standardisierungsgremien durchzubringen, und haben die Verfahren auch durchlaufen.
      Wenn ich mich richtig erinnere, war ein Hauptgrund für das Scheitern, dass NaCl eine zu „große“ Technologie und asm.js eine zu „kleine“ Technologie war, sodass asm.js trotz eines um mehrere Jahre späteren Starts zuerst produktionsreif wurde
    • Ich glaube, gemeint ist, dass Chrome es durchgedrückt hätte, Apple weiter Zeit geschunden hätte, indem es kaum in das WebKit-Team investiert und ansonsten nichts sagt, und die leichtgläubigen Leute im Internet sich auf Apple eingestellt hätten.
      Allerdings scheint Apple seit dem Beginn ernsthafter Regulierung in diesem Jahrzehnt die WebKit-Investitionen erhöht zu haben, daher könnte das Ergebnis heute anders ausfallen
    • Beschwerden gibt es, wenn es keine hochkompatible Alternative für Funktionen gibt, die auf der Webplattform nützlich wären. asm.js und später Wasm waren genau diese Alternative.
      Deshalb gab es damals weniger Beschwerden, und heute beschwert man sich über Dinge, die Safari nicht macht, weil sie dem App Store schaden würden. Zum Glück versucht die EU inzwischen, Apple in dieser Hinsicht etwas geradezurücken
  • Traurig, aber nachvollziehbar. Eine interessante Tatsache ist, dass Figma ursprünglich mit einer vollständigen C++-Codebasis gestartet ist und asm.js der Schlüsselbeweis dafür war, dass ein Design-Tool im Browser laufen kann.
    Auf WebAssembly umgestellt hat man erst, nachdem es zahlende Kunden gab, und die Verbesserung der Ladezeiten war ziemlich groß. asm.js ist immer noch JS, daher ist das Bundle größer und der Code muss als AST geparst werden, bei WASM ist das nicht so

    • Ich weiß nicht, was daran so traurig sein soll. Es ist nur ein Kompilierungsziel, das einmal Bedeutung hatte.
      So ähnlich, wie traurig zu sein, weil die Unterstützung für i386-unknown-freebsd1 weggefallen ist
    • Traurig ist, dass wir stattdessen vielleicht eine saubere native Figma-Desktop-App hätten haben können
  • Ist jetzt also der Tod von asm.js gekommen? Wir entfernen uns von der prophetischen Zeitlinie.
    https://www.destroyallsoftware.com/talks/the-birth-and-death...
    Falls du es noch nicht gesehen hast: absolute Empfehlung. Je nachdem, wie man „das Beste“ definiert, könnte es der beste Tech-Vortrag aller Zeiten sein

    • Mit dem Tod dieser Technologie wurde der Faden der Prophezeiung durchtrennt. Man kann entweder einen Spielstand laden und das Gewebe des Schicksals wiederherstellen oder weiter in der selbst verursachten verdammten Welt ausharren
    • Diesen Vortrag sehe ich mir zwei- bis dreimal im Jahr wieder an. Er ist ein großartiges Beispiel dafür, wie man präsentiert und wie man ein Slide-Deck auf den Vortrag abstimmt, und er bietet überraschend lehrreiche Einblicke in die Privilegienring-Struktur von Betriebssystemen.
      Irgendwann, nach einer Zeit des Krieges und nachdem sich die psychologische Fixierung auf veraltete Programmierparadigmen gelöst hat, könnten wir zu fortschrittlicheren Ansätzen übergehen. Das heißt natürlich nicht, dass deine Bank in den nächsten mindestens 85 Jahren kein YavaScript mehr ausführen wird
    • Wenn man einfach asm.js durch WASM ersetzt, ist man immer noch auf dem richtigen Weg
    • Keine Sorge. YavaScript wird ewig weiterleben
    • Wenn man Krieg durch COVID ersetzt, liegt es nicht weit daneben, denn beides ist 2020 passiert. Ob es wirklich stimmt, sehen wir aber wohl erst 2035
  • Ich werde nie den Moment vergessen, als ich Gary Bernhardts JavaScript-Vortrag gesehen habe.[0] Damals habe ich zum ersten Mal von asm.js erfahren und bin in den Kaninchenbau des Kompilierens von Code zur Ausführung im Browser gefallen.
    12 Jahre später erstaunt es mich, wie viel von seiner Fiktion Realität geworden ist.
    [0] https://www.destroyallsoftware.com/talks/the-birth-and-death...

    • Der Teil über „thick apps“ ist mir immer im Gedächtnis geblieben. Schon der Name war lustig, und es lag auch ziemlich nah an meiner eigenen Situation.
      Als ich den Vortrag zum ersten Mal sah, war ich Praktikant, und mein Unternehmen baute Compiler, IDE und Debugger komplett selbst für kleine industrielle IO-Boxen. Der Compiler war in C geschrieben, wurde mit Emscripten in JS umgewandelt und dann zusammen mit IDE- und Debugger-Teilen in eine riesige HTML-Datei „kompiliert“ — eigentlich eher zusammengeklebt. Code-Upload und Debugging liefen über Ethernet, und alles wurde per Ajax hineingeschoben.
      Das klingt nach einer verfluchten Architektur, aber die Kunden liebten es. Es war keine EXE und blieb daher nicht in den überzogenen Unternehmens-IT-Filtern der Kunden hängen. Deshalb sind wir nicht auf Electron umgestiegen. In gewisser Weise hatte es also primitive Elemente einer Thick App
    • Ohne den Aufstieg von AI hätte WASM vielleicht das maschinennahe Kompilierungsziel für alle Sprachen werden können. Gary hat vieles vorhergesehen, aber AI hat er nicht kommen sehen
  • Vor langer Zeit habe ich in einem WebGL-Buch ein kleines Kapitel über asm.js geschrieben.
    https://webglinsights.github.io/
    Es war spannend, den Aufstieg von asm.js zu beobachten, dem Vorläufer von WebAssembly. Unter den frühen Demos waren wirklich beeindruckende Dinge, etwa Unreal Engine, das im Browser lief. Es ist bittersüß, hier den Sonnenuntergang zu sehen, aber daraus ist viel Besseres entstanden

  • Vielleicht braucht es einen Transpiler von asm.js nach WASM.
    Legacy-Code mit alten Emscripten-Versionen zu kompilieren ist ziemlich frustrierend. Manchmal ist es fast genauso schmerzhaft, den JS-Code an die über die Jahre aufgelaufenen ABI-Änderungen von Emscripten anzupassen

    • Binaryen hatte früher ein asm2wasm-Tool, aber soweit ich weiß, wurde es inzwischen entfernt. Eine andere gleichwertige Lösung habe ich nicht gefunden.
      Zumindest wird asm.js-Code weiter funktionieren, selbst wenn asm.js-Optimierungen abgeschaltet sind, aber ein Konverter wäre schön
    • https://porffor.dev/
  • asm.js ist tot! Lang lebe WebAssembly!

    • Fairerweise muss man sagen, dass asm.js mit dem Aufkommen von wasm doch eigentlich schon vor Jahren zur Abschaffung vorgesehen war
  • Ich persönlich halte diese Entscheidung für einen Fehler. Wie groß die realen Auswirkungen sein werden, weiß ich allerdings nicht. Meines Wissens nutzen ohnehin nicht mehr viele Leute asm.js.
    Aber wasm ist viel zu stark von JavaScript isoliert. Nachdem ich es nur begrenzt ausprobiert habe, dachte ich mir eher, ich sollte vielleicht lieber nach asm.js kompilieren.
    Ich war mir nicht einmal sicher, ob Emscripten das noch vollständig unterstützt.
    In wasm kann man die meisten Web-APIs nicht aufrufen.
    Für das, was ich machen wollte, war noch wichtiger, dass man von JS aus keine Zero-Copy-Buffer an wasm übergeben kann.
    Alles ist ein Kompromiss. Die Isolation ist ein Vorteil, aber eben auch ein Nachteil

    • asm.js wäre in der Interaktion mit JS definitiv eingeschränkter als wasm. Im Grunde ist man dort auf einfache Zahlenwerte und Array-Buffer beschränkt.
      Modernes wasm hat dagegen GC-Typen, und mit externref kann man auch JS-Werte festhalten.
      Zero-Copy-Buffer gehen in asm.js wahrscheinlich ebenfalls nicht. Auf der wasm-Seite gibt es einen Vorschlag für Zero-Copy-Buffer: https://github.com/WebAssembly/memory-control/blob/main/prop...
    • Wenn ich mich richtig erinnere, hat Emscripten die asm.js-Unterstützung ungefähr 2020 entfernt, und das war wohl die wichtigste Toolchain, die asm.js unterstützt hat. Danach vielleicht Rust, aber ich weiß nicht, ob es das noch unterstützt.
      Selbst in strengem asm.js kann man die meisten Web-APIs nicht direkt aufrufen. Es unterstützt nur Zahlen, keine JS-Strings oder -Objekte, und verwaltet den C-Heap wie WASM innerhalb eines ArrayBuffer-Objekts.
      Bei Zero-Copy-Buffern ist es dasselbe Problem. Man muss aus asm.js in „echtes“ JavaScript herausspringen, um den Aufruf zu machen, und man kann einen anderen ArrayBuffer auch nicht direkt in den asm.js-Heap einblenden, daher ist Kopieren erforderlich. Die „JavaScript-FFI“ unterscheidet sich zwischen asm.js und WASM praktisch nicht stark
    • Wenn ich das nicht missverstehe, hat asm.js doch dieselben Einschränkungen, oder? Man kann also Web-APIs aus asm.js-Code nicht direkt aufrufen, und für „externe“ Funktionen braucht man weiterhin eine Sonderbehandlung
  • Ich erinnere mich, als Mozilla OdinMonkey veröffentlichte, das extrem stark auf asm.js-Code spezialisiert war. Das Chrome-/V8-Team konzentrierte sich stattdessen auf allgemeine JIT-Optimierungen, die normales JavaScript schneller machen und dabei auch asm.js helfen würden.
    Der Geschwindigkeitsunterschied sprach mit dem Faktor 2 bis 4 für Firefox, und das wurde ziemlich offensiv beworben :D
    Heutzutage haben sich die meisten JavaScript-VMs in Browsern auf sehr ähnliche Designs und Optimierungen angenähert, daher würde asm.js-Code wohl auch ohne Odin ohnehin ziemlich schnell laufen

  • Damit ist mein Plan dahin, zur Laufzeit JS-Code zu erzeugen, um Algorithmen schneller zu machen. Mit wasm dürfte das deutlich schwieriger sein

    • Wasm-Code zur Laufzeit zu erzeugen ist ziemlich einfach. Es könnte sogar einfacher sein, als gültigen asm.js-Code zu erzeugen.
      Für Tests gibt es eine kleine Bibliothek, die einen großen Teil davon übernimmt: https://searchfox.org/firefox-main/source/js/src/jit-test/li...
    • Mit einer Bibliothek ist es nicht schwieriger. In Rust würde man dafür so etwas verwenden: https://crates.io/crates/wasm-encoder
      In JS wahrscheinlich https://www.npmjs.com/package/binaryen
    • Es gibt immer noch AssemblyScript. Falls ich das nicht missverstehe oder die Funktion falsch im Kopf habe, könnte es zu den Anforderungen passen.
      https://www.assemblyscript.org/
    • Man kann auch einfach das asm.js-Subset verwenden und sehen, wie die Performance ausfällt. Ich erinnere mich, dass die Performance der Emscripten-Ausgabe selbst ohne spezielle asm.js-Unterstützung im Browser überraschend gut war
    • Es wird weiterhin funktionieren. asm.js ist letztlich ganz normaler JavaScript-Code.
      Er wird nur nicht so schnell geparst oder ausgeführt wie mit einer asm.js-spezifischen Pipeline. Wenn es keine riesige Anwendung ist, wird man den Unterschied wahrscheinlich kaum bemerken