asm.js
此條目翻譯自其他語言維基百科,需要相關領域的編者協助校對翻譯。 |
設計者 | Mozilla |
---|---|
釋出時間 | 2013年3月21日[1] |
作業系統 | 平台無關 |
網站 | asmjs |
啟發語言 | |
JavaScript |
asm.js是一個中間語言,設計目的是使採用C等程式語言編寫的電腦軟件可執行為網絡應用程式,同時效能特徵明顯優於標準JavaScript。
asm.js包括一個JavaScript的嚴格子集,其中的代碼採用具有手動主記憶體管理的靜態型別語言(就像C語言)編寫,代碼使用一個原始碼至原始碼編譯器(例如基於LLVM的Emscripten)翻譯。通過將語言特性限制在適合提前最佳化和其他效能改進的範圍內,效能得到了提高。
Mozilla Firefox是第一個實現針對asm.js最佳化的瀏覽器,從Firefox 22開始使用。[2]
設計
[編輯]asm.js由JavaScript語言的一個嚴格子集組成。它可以顯著提高採用具有手動主記憶體管理(例如C)的靜態型別語言編寫的網絡應用程式在使用原始碼至原始碼編譯器轉換為JavaScript後的效能。Asm.js的目標並不是提高手寫JavaScript代碼的效能,也不實現增強效能以外的其他目的。
通過將語言特性限制在適合提前最佳化和其他效能改進的範圍內,其旨在具有比標準JavaScript更接近於本地(原生)代碼的效能特徵。[3]通過使用JavaScript的一個子集,asm.js很大程度上支援所有主要的網頁瀏覽器[4],這不同於WebAssembly或Google Native Client等途徑。
代碼生成
[編輯]asm.js通常不直接編寫,而是作為一種通過編譯器生成的中間語言,該編譯器取得C++或其他語言的原始碼,然後輸出asm.js。
例如,提供下列C語言代碼:
int f(int i) {
return i + 1;
}
Emscripten將輸出下列JavaScript代碼:
function f(i) {
i = i|0;
return (i + 1)|0;
}
注意新增的|0
和去除的類型說明符。在JavaScript中,按位元運算子會將運算元轉換為32位元有符號整數並給出整數結果。這意味着使用0的按位元OR為一個無作用的操作,只是將值轉換為整數。通過對每個參數這樣做,確保了從外部代碼呼叫該函數時,該值被轉換為正確的類型。這也用於返回值,在該情況下確保添加1到i的結果將是一個整數(否則可能變得太大),並標記函數的返回類型。這些轉換為asm.js所必需,這樣最佳化編譯器才可以提前生成高效的本地代碼。在此類最佳化編譯器中,當asm.js代碼呼叫其他asm.js代碼時,轉換不執行,因為必需的類型說明符意味着已保證值具有正確的類型。此外,不同於執行浮點加法和轉換為整數,它可以簡單地執行本機整數運算。這樣一來,它可以得到顯著的效能增益。
下面是另一個計算字串長度的例子:
size_t strlen(char *ptr) {
char *curr = ptr;
while (*curr != 0) {
curr++;
}
return (curr - ptr);
}
它對應以下asm.js代碼:
function strlen(ptr) {
ptr = ptr|0;
var curr = 0;
curr = ptr;
while (MEM8[curr]|0 != 0) {
curr = (curr + 1)|0;
}
return (curr - ptr)|0;
}
在生成的代碼中,變數MEM8實際上是一個類型緩衝區的逐位元組「視圖」,它充當asm.js代碼的堆(heap)。
效能
[編輯]因為asm.js在瀏覽器中執行,所以效能很大程度上取決於瀏覽器和硬件。編譯為asm.js的C程式的初步基準通常比使用Clang的本地編譯慢一倍以上。[5]
這種超過普通JavaScript的效能增益主要是由於100%的類型一致性以及幾乎沒有垃圾回收(主記憶體是手動管理的大型類型陣列)。這個更簡單的模型沒有動態行為,沒有主記憶體分配或釋放,只有一組簡單、定義明確的整數和浮點操作,從而可實現更好的效能和最佳化潛力。[來源請求]
Mozilla在2013年12月的基準測試顯示:「使用float32最佳化的Firefox可以執行所有基準,只比原生速度慢不到1.5倍。[6] Mozilla指出本地編譯代碼的效能不是單個度量,而是一個範圍,使用不同的本地編譯器(此例中為Clang與GCC)將提供不同效能的代碼。「事實上,在一些基準測試比如Box2D、FASTA和copy中,asm.js與Clang比較接近,或者比Clang到GCC還接近Clang。在一種情況下,asm.js甚至在Box2D上略微擊敗Clang。」
實現
[編輯]Emscripten專案提供了可以編譯C和C++(或其他任何可轉換為LLVM IR的語言)代碼為asm.js的工具。[7]
所有支援JavaScript較新版本的瀏覽器都應該能支援執行asm.js代碼,因為它是該規範的子集。
部分瀏覽器的實現針對asm.js進行了特別最佳化:
- Mozilla Firefox是第一個實現針對asm.js最佳化的網頁瀏覽器,自Firefox 22開始使用。 OdinMonkey是Mozilla在Firefox中使用的asm.js提前編譯器,它是IonMonkey(SpiderMonkey的JIT編譯器)的一個組件。
- 微軟在Microsoft Edge使用的JavaScript引擎Chakra中實現了asm.js支援,執行驗證以產生高度最佳化的JIT代碼。[8]
- Google Chrome的V8 JavaScript引擎在Chrome 28中對asm.js基準測試的效能是以前Chrome版本的兩倍以上,[9]儘管Chrome的V8沒有使用提前編譯。
採用
[編輯]目前幾乎所有基於asm.js的應用程式都是使用Emscripten或Mandreel編譯為asm.js的C/C++應用程式。
到目前為止,已有不少程式語言、應用程式框架、程式、函式庫、遊戲、遊戲引擎及其他軟件已被移植。[10]部分名單見下:
程式語言
[編輯]- C/C++:Clang和LLVM
- Lua VM:Lua 虛擬機器[11]
- Perl:(micro)perl-5.16.3的移植[12]
- Python – CPython移植[13]
- Ruby – Ruby移植[14]
應用程式框架
[編輯]程式和庫
[編輯]- OpenGL、SDL和SDL2[17]
- Vim(Vi IMproved)[18]
- FreeType:在JavaScript中使用FreeType的TrueType字型光柵化[19]
- SQLite[20]
- GNU Privacy Guard[21]
- ctags[22]
- gnuplot[23]
- Graphviz[24]
- zlib[25]
遊戲引擎
[編輯]遊戲
[編輯]- Doom:執行在PrBoom上的開源Freedoom遊戲assets,基於開源的Doom代碼[31]
- SuperTux[32]
- Dune II via OpenDune[33]
- BananaBread based on Cube 2[34]
- Humble Mozilla Bundle中的每個遊戲[35](Super Hexagon、輕率漠視重力、Osmos、Zen Bound 2、Dustforce DX、Voxatron、FTL: Advanced Edition和Democracy 3)
仿真器
[編輯]數學計算
[編輯]- HTML5 Fractal Playground[38] – 繪製迭代函數生成的分形,例如Mandelbrot fractal。
參見
[編輯]- WebAssembly – 一個開發中的用於瀏覽器的位元組碼,旨在比asm.js更快地解析
RPython - CrossBridge
- Google Native Client(NaCl)
參考資料
[編輯]- ^ asm.js in Firefox Nightly. Luke Wagner's blog. 21 Mar 2013 [13 Nov 2014]. (原始內容存檔於2017-04-21).
- ^ Firefox 22.0 release notes. Mozilla. [July 4, 2013]. (原始內容存檔於2014-08-21).
- ^ Asm.js. Asm.js. [2015-03-05]. (原始內容存檔於2015-03-06).
- ^ asm.js — frequently asked questions. Asmjs.org. July 26, 2014 [2017-03-15]. (原始內容存檔於2014-06-04).
- ^ asm.js. Asm.js. [2015-03-05]. (原始內容存檔於2014-06-04).
- ^ Alon Zakai; Robert Nyman. Gap between asm.js and native performance gets even narrower with float32 optimizations. 20 December 2013 [11 April 2014]. (原始內容存檔於2017-03-31).
- ^ kripken/emscripten · GitHub. Github.com. [2015-03-05]. (原始內容存檔於2015-03-03).
- ^ Bringing Asm.js to Chakra and Microsoft Edge. Microsoft. May 7, 2015 [May 7, 2015]. (原始內容存檔於2017-03-31).
- ^ Chrome 28 Beta: A more immersive web, everywhere. Google. [2013-07-06]. (原始內容存檔於2016-09-15).
- ^ Home — Demos — Games and Game Engines. [2017-03-15]. (原始內容存檔於2017-03-20).
- ^ Lua REPL. Kripken.github.io. [2015-03-05]. (原始內容存檔於2015-02-17).
- ^ plu. Themucker.github.io. [2015-03-05]. (原始內容存檔於2014-06-15).
- ^ repl.it — Python. Repl.it. [2015-03-05]. (原始內容存檔於2015-03-06).
- ^ repl.it — Ruby. Repl.it. [2015-03-05]. (原始內容存檔於2015-03-03).
- ^ pepper.js Examples. Trypepperjs.appspot.com. [2015-03-05]. (原始內容存檔於2020-02-14).
- ^ emscripten-qt — Demos. Vps.etotheipiplusone.com. [2015-03-05]. (原始內容存檔於2015-02-13).
- ^ About Emscripten. [2017-03-15]. (原始內容存檔於2017-03-16).
- ^ Vim.js — JavaScript port of Vim. Coolwanglu.github.io. [2015-03-05]. (原始內容存檔於2017-10-19).
- ^ TrueType Fonts in JavaScript. [2017-03-15]. (原始內容存檔於2012-10-12).
- ^ Port of SQLite to Javascript. Github.com. [2015-03-05]. (原始內容存檔於2015-02-16).
- ^ GnuPG.js. Manuuels.github.io. [2015-03-05]. (原始內容存檔於2015-04-25).
- ^ ctags in the browser. Github.com. [2015-03-05]. (原始內容存檔於2019-02-15).
- ^ Gnuplot online. Gnuplot.respawned.com. [2015-03-05]. (原始內容存檔於2015-02-22).
- ^ A hack to put GraphViz on the web.. Github.com. [2015-03-05]. (原始內容存檔於2015-02-22).
- ^ JavaScript port of ZLib DEFLATE for the browser. Github.com. [2015-03-05]. (原始內容存檔於2014-12-05).
- ^ Epic Games Releases ‘Epic Citadel’ on the Web. UnrealEngine.com (新聞稿). May 2, 2013 [2017-03-15]. (原始內容存檔於2016-11-30).
- ^ Unreal Engine 3 ported to JavaScript and WebGL, works in any modern browser. ExtremeTech. Ziff Davis. [2015-03-05]. (原始內容存檔於2015-03-10).
- ^ On the future of Web publishing in Unity. Blogs.unity3d.com. April 29, 2014 [2017-03-15]. (原始內容存檔於2014-07-27).
- ^ HTML5. Clb.demon.fi. [2015-03-05]. (原始內容存檔於2015-03-06).
- ^ Compiling for the Web. godotengine.org. November 10, 2016 [2017-03-15]. (原始內容存檔於2017-01-13).
- ^ Emscripten-Generated Code. Kripken.github.io. [2015-03-05]. (原始內容存檔於2015-02-23).
- ^ Emscripten-Generated Code. Forandom.github.io. [2015-03-05]. (原始內容存檔於2015-03-15).
- ^ Guryanov Aleksander. Dune 2 - Online (browser version). Epicport. [2015-03-05]. (原始內容存檔於2015-03-10).
- ^ Mozilla Banana Bread Demo. Developer.mozilla.org. [2015-03-05]. (原始內容存檔於2015-03-04).
- ^ Humble Mozilla Bundle pushes WebGL-powered browser gaming. Ars Technica. 15 Oct 2014 [15 Oct 2014]. (原始內容存檔於2014-10-16).
- ^ EM-Dosbox on Github. [2015-04-09]. (原始內容存檔於2015-03-29).
- ^ Page Redirection. Jsmess.textfiles.com. [2015-03-05]. (原始內容存檔於2015-03-05).
- ^ HTML5 Fractal Playground. Danielsadvernture.info. [2015-03-05]. (原始內容存檔於2015-02-22).
外部連結
[編輯]- 官方網站
- GitHub上的asm.js頁面
- Asm.js: The JavaScript Compile Target(頁面存檔備份,存於互聯網檔案館)
- RPerl(頁面存檔備份,存於互聯網檔案館)
- Asm.js usage per Google Chrome statistics(頁面存檔備份,存於互聯網檔案館)