asm.js Emscripten WebAssembly

參考
Emscripten與拼音輸入法的相遇
VS2010 c/c++ 本地化 emscripten 配置
大家對Emscripten這個項目有什么想法
Web3D Porting - Emscripten VS FlasCC
HTML5標準與性能之四:asm.js
【探索】在 JavaScript 中使用 C 程序
asm.js:面向未來的開發
asm.js
Emscripten

一、asm.js Emscripten

在提到 Emscripten 之前,我們先來回顧一下 JavaScript 的發展歷史。
JavaScript 的歷史
JavaScript在1995年問世的時候,目的是在瀏覽器中打造一種輕量的腳本語言,用來輔助頁面的呈現以及與使用者互動。為了這個目的,JavaScript被設計的非常靈活,讓開發者在撰寫過程中不會被太多的規則所限制。雖然在保持靈活性的同時可能會犧牲效率,但如果JavaScript只是被用來提高網頁的互動性的話,似乎也不會有什么大問題。
但是科技的趨勢總是難以預料的,應用程序的領域漸漸從操作系統轉移到了網絡環境中,Web應用變成了熱門關鍵字,JavaScript的效率這時成了最大的瓶頸。終于在2008年左右,各家瀏覽器開始放出支持JIT(Just-In-Time)編譯的JavaScript引擎,讓瀏覽器可以在它判斷需要時將部分的JavaScript代碼即時編譯成源代碼來執行,性能因此得到提升。
JIT引擎雖然解決了當時的瓶頸,但JavaScript的性能還是沒辦法和真正的源代碼相提并論,主要的限制就在于JavaScript的靈活性讓它不容易被優化。舉例來說,JavaScript選擇采用與大部分的腳本語言相通的動態類型機制(dynamic typing),在編輯時沒有辦法確定變量的形態,因此JIT引擎就必須為之后在執行時可能進行的各種變量形態轉換提前做準備,浪費了很多資源。
asm.js 與 Emscripten
為了解決此類問題,David Herman、Luke Wagner 和 Alon Zakai 等人提出了一種JavaScript 的子集,命名為asm.js。這個子集的目的是讓開發者避開JavaScript中無法最佳化的部分,例如:不直接使用JavaScript的對象,改為通過長矩陣來模糊記憶體的管理,避免使用引擎的garbage collection等等。由于asm.js單純是JavaScript的子集,并沒有加入任何新的語法,所以寫出來的代碼在所有的瀏覽器上都是可以被解析和執行的,只是當瀏覽器真正支持asm.js的規范時,其JIT引擎就能采用更有效率的最佳方式來進行編譯,進而獲得更好的執行效率。

圖一、Emscripten 編譯出來的程序代碼片段

圖一使用Emscripten編譯出來的JavaScript程序代碼片段,你應該可以想象如果要用人腦寫出如何asm.js規范的程序代碼,似乎不是那么容易(這就是為什么它會以組合語言asm命名)。事實上,Mozilla并不打算讓人直接撰寫asm.js,他們開發了一個叫做Emscripten的編譯器,讓開發展可以直接把C/C++的源代碼“編譯”成JavaScript的程序代碼,聽起來是不是輕松多了!

asm.js是由Mozilla提出的一個基于JS的語法標準,主要是為了解決JS引擎的執行效率問題,尤其是使用Emscripten從C/C++語言編譯成JS的程序的效率,目前只有Mozilla的Firefox Nightly中支持。

Emscripten是一個基于LLVM的項目,可以把C和C++代碼編譯成高度優化的JavaScript代碼(asm.js格式),可以在web中以近乎原生的速度運行C和C++代碼,而且不需要插件。

Emscripten是Mozilla的一個實驗性項目,目的是把C/C++開發的應用編譯成JS或HTML5的應用,編譯過程中需要首先把C/C++程序編譯成LLVM的中間代碼,然后再轉換成JS代碼,這樣做的主要原因是可以很好地復用現有的針對LLVM的優化。

asm.js的目標比typescript、dart、pnacl都要大的多,它有可能成為web未來的基礎設施。簡單說,它可能成為web上的jvm或.net,你可以把asm.js的代碼看成未來web平臺的bytecode。未來jvm及.net平臺的語言也可以編譯到asm.js,而不僅僅是c、c++,這實際意味著:未來所有的語言都應該可以編譯為asm.js,從而使web擺脫js(或加上dart等極少數幾種語言)的限制。ECMAScript6/7、dart再好,也不可能滿足所有人的需求。

二、Emscripten與FlasCC

Emscripten的主要流程為:

C/C++ -> LLVM -> Emscripten -> JavaScript/HTML

其編譯環境配置相對來說較為簡單,可以見這里有比較詳細的介紹。本人參考在VS里邊配置了一下但是沒有成功,不過不使用VS的話倒也沒什么影響,簡單寫一個bat也可以完成編譯的流程。
FlasCC的主要流程為:

C/C++ -> GCC -> LLVM -> FlasCC -> .abc -> SWF

FlasCC的編譯環境相對來說就比較高了,其它的如Java,Python等都不說了,除此外主要就是需要Cygwin的環境(這空間很可觀,跟NDK環境配置有得一拼);還有一點就是FlasCC的64位環境要求,否則32位下的內存搞不定,囧。。。
整體來說FlasCC要求的編譯環境比Emscripten要高不少。

三、Emscripten測試

1.需要先安裝一下notepad++編輯器的C語言環境,參考MinGW的安裝以及如何配置C,notepad++搭建C語言環境(Dev c++)
2.安裝好Emscripten
參考emscripten getting start
3.測試
寫一個hello.c。然后CMD進入相應路徑后,運行命令emcc hello.c -o hello.html

#include<stdio.h>

int main() {
  printf("hello, world! by cuixu\n");
  return 0;
}
四、WebAssembly字節碼技術

如何評論瀏覽器最新的 WebAssembly 字節碼技術?

作者:余建榮
鏈接:https://www.zhihu.com/question/31415286/answer/51902492
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

一個常見的asm.js應用形式就是Emscripten,在這個項目里,C++代碼將會被Clang編譯為LLVM bitcode,然后LLVM bitcode再被Fastcomp (emscripten的編譯后端) 編譯為插入了特殊標記的JS(也就是asm.js),這樣的JS在普通JS引擎能運行,但在對Asm.js優化的引擎里可以得到巨大的性能提升。但這樣的解決方案有一個問題:編譯出來的JS文件非常巨大,這樣會嚴重增加加載時間。回到上面的應用形式,我們發現既然這樣的JS是LLVM bitcode再編譯的,那直接傳輸LLVM bitcode不就行了嗎?當然以LLVM bitcode為標準是不可取的(一個是未必足夠優化,一個是web標準可不能和某個特定的解決方案掛鉤),所以就有了所謂的WebAssembly了……所以WebAssembly是這樣一個解決方案:1. 二進制,可以完全編譯到對應的asm.js2. 一個用于不支持WebAssembly的JS引擎的polyfill,也就是要做一個JS版的WebAssembly到asm.js的編譯器所以可以看出來:1. WebAssembly的運行性能和asm.js沒有任何區別2. 主要優點是在減少傳輸體積和提高parse性能上

作者:羅志宇鏈接:https://www.zhihu.com/question/31415286/answer/58022648來源:知乎著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
既然 JIT 遇到的問題是類型不確定問題和有一些語言功能,比如異常,for in , JIT 起來很麻煩, 我可不可以搞個方法讓用戶不去用這些功能,同時讓他們把用的類型都標注出來啊。
按照這個思路, 催生了兩種實現路徑:
一種是 Typescript, Dart, JSX 為代表的,基本思想是, 我搞個其他的語言,這個語言是強類型的,所以程序猿們需要指定類型,然后我把它編譯成 Javacript 不就行了嘛。強類型的語言編譯成弱類型還不容易,什么,不知道怎么編? 把類型去掉就行了嘛。
另一種是火狐的 Asm.js 為代表的, 做一個 javascript 子集, 同時試圖利用標注的方法,加上變量類型, 如果覺得好難理解,這就是個典型的例子:

Paste_Image.png

加上一堆沒有什么卵用提示 x 其實是個 int, 然后有一個能夠識別這些符號的JS引擎,你就可以不用猜類型了哦, 事實上,由于有了類型,連傳統的 AOT 都成為了可能(Ahead of time, 不懂的話,想象一下,就是和 C/C++ 那種編譯方式就好了)。如果你沒有注意到,第二種的速度提升潛力比第一種要大非常多。因為第一種,無論如何,也是就是讓JIT (即時編譯) 快一點, 第二種那可直接就編譯了啊 (AOT).

Web Assembly 就是第二種方式,說到底,Mozilla, Google,Microsoft,Applel 覺得 Asm.js 這個方法有前途,想標準化一下,大家都能用。
有了大佬們的支持,Web Assembly 比 asm.js 要激進很多。 Web Assembly 連標注 Js 這種事情都懶得做了,不是要 AOT 嗎? 我直接給字節碼好不好?(后來改成 AST 樹)。對于不支持 Web Assembly 的瀏覽器, 會有一段 Javascript 把 Web Assembly 重新翻譯為 Javascript 運行, 這個技術叫 polyfill, HTML5 剛出來的時候很常用的一個技術。

https://zhuanlan.zhihu.com/p/25800318
https://zhuanlan.zhihu.com/p/25669120

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容