參考
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編譯出來的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字節碼技術
作者:余建榮
鏈接: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 子集, 同時試圖利用標注的方法,加上變量類型, 如果覺得好難理解,這就是個典型的例子:
加上一堆沒有什么卵用提示 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