天天看點

WebAssembly 新鮮事兒

更好的閱讀體驗歡迎移步 WebAssembly 新鮮事兒

本周的 wasm 大新聞莫過于阮老師發的一條 twitter:

厲害了,Windows 2000 被編譯成 WebAssembly,可以在浏覽器裡跑了。 https://t.co/CdLH3hB1Ru https://t.co/CdLH3hB1Ru pic.twitter.com/wAWkuCoUTd — ruanyf (@ruanyf) 2018年8月21日

體驗下來确實很驚豔,大家都開玩笑說終于可以在 Chrome 裡打開 Firefox 了,隻是需要一點耐心 hmm...

不過,阮老師又一次搞了個大新聞,Windows 雖然底層是有很多 C 代碼,但并不像 Linux 開源,既然都拿不到源碼又何來被編譯成 wasm 之說呢? 那真相是什麼樣子呢?作者 Fabrice Bellard 又是何方大神?

Windows 2000 on JSLinux

在這個頁面底部的

Technical notes

連結裡,我們可以找到一些技術細節。原來背後是 Bellard 開發的 JSLinux 這個東西,它是一個用 JavaScript 編寫的可以運作在浏覽器環境的模拟器,大概可以類比到 vmware/virtualbox。算下來接近 8 個年頭了,2011 年時 Bellard 編寫了初代版本的 JSLinux,也是用 JavaScript 編寫的可以跑 Linux 的首個 PC/x86 的模拟器,複用了 Bellard 另一個牛逼的工具

QEMU

實作 x86 的輔助功能和裝置模拟。

之後在 2015 年切換到使用

asm.js

來提升性能,2016 年在開發

riscvemu

(一個

RISC-V

模拟器) 後,Bellard 決定使用

emscripten

從 C 代碼輸出 JavaScript 版本,并且還開發了

VirtIO

9P 檔案系統便于使用遠端檔案系統以及檔案導入導出,接下來 Bellard 發現複用 VirtIO 裝置到 x86 JS 模拟器很有趣,于是把 JSLinux 的 asm.js 版本的代碼轉為 C 再通過

轉回 JavaScript,通過細緻的調優之後新的版本比原來手寫的 asm.js 版本更快了。

這之後 JSLinux 就不再隻局限于 Linux 系統了,開始向 Windows NT 進軍了,目前版本的 JSLinux 模拟了缺失的幾個 PC 裝置(PS/2 鍵鼠、VGA 等),已經可以運作 Windows NT 了。

說了這麼多,那到底真相是什麼呢?找到一張圖,雖然不是直接相關(

《jsmodem - 讓 jslinux 使用網路功能》

,講的是 JSLinux 裡模拟 modem 的實作),大體也差不多了:

WebAssembly 新鮮事兒

簡單說大約是 JSLinux 跑在浏覽器的 JS 引擎之上,提供一層虛拟機,然後加載了 Windows 2000 的系統跑了起來。當然實際細節要複雜得多,如果你打開浏覽器控制台,觀察一下請求,會發現初始階段加載的 wasm 其實體積并不大,後面會不斷異步拉取

.bin

檔案,看起來是基于 Windows 2000 的鏡像做了細粒度的拆分,而且在互動上也會發現随着互動的進行,源源不斷會阻塞去按需加載新的

.bin

檔案回來。

WebAssembly 新鮮事兒

話說回來其實 JSLinux 支援 Windows 2000 是

去年 9 月的事情

了,這周突然在社群熱鬧起來大約是因為

大佬 Steven Sinofsky (前微軟 Windows 事業部總裁)的 twitter

, 加上阮老師應該也是看了下面這條來自

WebAssemblyWeekly 公共賬号

的傳播。相比去年主要就是模拟器部分開始有了 wasm 的支援,是以得到了大家的關注和 wasm 社群的雀躍。

Window 2000 emulated in WebAssembly https://t.co/l7f8au2Zk5 https://t.co/l7f8au2Zk5 pic.twitter.com/U9fg3w3ZRh — WebAssemblyWeekly (@WasmWeekly)

Fabrice Bellard 大神

接下來簡單八一下作者 Fabrice Bellard 大神,前面的介紹裡已經多次說到 Fabrice Bellard 大神各種造工具的記錄了,這位大神到底什麼來頭?他還有些什麼傑作?知乎上有個問題:

《Fabrice Bellard是個什麼水準的程式員?》

,搬運一下:

作者:Hao Lee

連結:

https://www.zhihu.com/question/28388113/answer/150897437

來源:知乎

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

确實是奇才, 單是 FFmpeg 和 Qemu 這兩項就足以超越絕大部分程式員了。看到他的成就我的第一反應就是這哥們兒能和 Linus Torvalds 拼一下(不一定幹得過,企鵝王體型比他大)。Fabrice Bellard 的計算機底層功力極其深厚,對各種細節了如指掌,虛拟機可不是想寫就能寫的,這需要熟悉CPU、記憶體、BIOS、磁盤的内部原理,滑鼠、鍵盤、終端等外圍裝置的工作流程,然後在軟體層面模拟出來,想想就複雜。從這一點上他可以被稱作天才程式員。另外,他的數學功底也是相當紮實,能發現計算圓周率的新算法并且改進算法的人又可以稱作計算機科學家。他一個人幾乎涵蓋了計算機領域的兩大發展路線,屬于那種全才型的人物。我等隻能仰視,無可企及。

下面,讓我們來按照時間順序看一看大神的人生軌迹:

  • 1972年,天才降生
  • 上大學之前重寫了LZSS壓縮算法,解壓軟體速度快體積小
  • 1997年1月20日,他釋出了最快速的計算圓周率的算法,此算法是 Bailey-Borwein-Plouffe 公式的變體,前者的時間複雜度是O(n^3),他給優化成了O(n^2),使得計算速度提高了43%,這是他在數學領域的成就。此時他僅有25歲,我特麼現在還在玩泥巴。
  • 2000年他化名Gérard Lantau,建立了FFmpeg項目,做過多媒體音視訊處理的應該都知道這個項目到底有多強大。現在暴風影音、QQ影音、格式工廠,還有YouTube、VLC等都使用了FFmpeg的編解碼函數庫,不過前三者因為不遵守開源協定已經被FFmpeg挂在官網昭告天下了(官網的頁面不知為何下線了,我找了份存檔 https://web.archive.org/web/20101214233906/http://ffmpeg.org/shame.html )。FFmpeg易擴充、功能強、速度快、占資源少,支援的音視訊格式極其廣泛,基本上超越了其他所有同類軟體,這是他在多媒體處理領域的巨大成就。
  • 2000-2001年左右,他赢得兩次國際混淆C代碼大賽(IOCCC),第一個作品寫了個4KB大小的C語言編譯器子集 OTCC ,這可以算作是TinyCC的前身;第二個作品寫了個475B大小的用于列印已知最大素數的程式,用傅裡葉變換做的,膜拜吧。
  • 2002年他釋出了TinyGL,這是OpenGL的一個子集實作,體積小速度快,占資源還少,這是他在圖像處理領域的成就。
  • 2003年開發了Emacs的一個變種:QEmacs。
  • 2004年8月他在之前OTCC的基礎上繼續完善,使之具備了能夠編譯Linux核心的能力,這就是TinyCC的正式版,簡稱TCC。為了證明TCC的威力,他又寫了一個隻有138KB的啟動加載程式TCCBOOT,可以在15秒内從源代碼編譯并啟動Linux核心。分分鐘就寫了個編譯器加引導器,怎麼樣,怕不怕,我已經躲在角落瑟瑟發抖了。
  • 2005年,Bellard 釋出了 QEMU,這是個爆炸性的項目,現在衆多底層開發人員已經離不開它了,相當的強大,作業系統教學領域也多用其作為示範。開發這玩意兒需要非常廣泛的底層硬體和作業系統知識,一般人搞不定。QEMU的技術已經被應用于KVM、XEN、VirtualBox等多個虛拟化項目中。他至少上司了QEMU項目4年,這是他在虛拟化領域的成就。同年,他用普通PC和VGA卡設計了一個數字電視系統。
  • 2009年12月31日,他聲稱打破了圓周率計算的世界紀錄,僅用一台普通PC機,耗時116天,算出了圓周率小數點後2.7萬億位,比2009年8月17日由超級計算機算出的世界紀錄多了1200億位 。憑借這個突出的數學貢獻,他登上了《科學美國人》法文版。
  • 2011年,他單用JavaScript寫了一個PC虛拟機Jslinux 。這個虛拟機仿真了一個32位的x86相容處理器,一個8259可程式設計中斷控制器,一個8254可程式設計中斷計時器,和一個16450 UART。想玩的來這裡: Javascript PC Emulator 。我覺得他寫這玩意兒的時候頭頂已經出現光環飄飄乎羽化而登仙了。
  • 不得不承認,這個世界真的有天才。

wasm 還有哪些驚豔的 demo

最近

wasm 1.0 版本的草案

終于釋出,

wasm 官網

上也挂出了四大主流浏覽器已提供 1.0 版本支援的消息。

Ending定律也将開始生效

。算起來從 2015 年 4 月

WebAssembly 社群工作組

成立到現在,wasm 才 3 歲,除了 Windows 2000,還有哪些驚豔的 wasm 的 demo 呢?

總的來說可以看到由于有衆多的 C/C++/Rust 開發的現有遊戲可以通過編譯到中間語言(IR),繼而編譯到 wasm,如下圖 Lin Clark 在 wasm 系列文章之一

《Creating and working with WebAssembly modules》

中的下圖所示,這讓移植成本變得相對輕松,也不奇怪看到很多 Rust 的遊戲可以轉到 wasm 版本。

WebAssembly 新鮮事兒

Lifoff in V8

另一條值得關注的與 wasm 有關的是 V8 官方部落格的更新:

《Liftoff: a new baseline compiler for WebAssembly in V8》

。在 V8 6.9 之前,wasm 在 V8 裡的運作隻能在 TurboFan 編譯器上,而 TurboFan 本身是為高性能執行而設計,短闆是啟動性能(因為要做深入優化,代碼生成速度慢),在 JS 的執行時 V8 裡有 Ignition 編譯器作為基線編譯器(baseline compiler)來解決快速啟動和記憶體占用的問題,而在 wasm 裡則沒有,是以這次引入了一個新的基線編譯器 Liftoff 來解決 wasm 的快速啟動問題。

WebAssembly 新鮮事兒

通過部落格上這張圖可以看到,相比 TurboFan,Liftoff 的代碼生成效率要高得多,而且博文中介紹到可以在解碼和驗證函數體的同時不斷地執行代碼生成,基于

wasm 的流式處理 API

,可以使 V8 在通過網絡下載下傳 wasm 的同時将 wasm 代碼不斷編譯到機器碼,加快啟動執行效率。

WebAssembly 新鮮事兒

從後文的圖也可以看出性能提升也是相當明顯的。

接下來還會有更多的優化,比如目前 Liftoff 還僅支援 Intel 平台 主要覆寫桌面使用者,接下來會移植到 arm 和 arm64 以支援移動裝置;針對移動裝置可用記憶體更少的情況實作動态的編譯層級提升;提升 Liftoff 的代碼生成性能以及生成的代碼的性能等。

随着 1.0 草案的落地,四大主流浏覽器的支援,今年大概真的可以算 wasm 元年了。浏覽器裡跑作業系統都已經不是夢,AutoDesk 也可以搬到浏覽器裡,未來還有什麼是不可取代的 B/S 呢?當然另一方面也意味着前端的版圖已經越來越廣闊,要學的東西更多了,如果你對 wasm 還沒有多少了解,不妨從 Lin Clark 的

《A cartoon intro to WebAssembly》

看起(中文翻譯版可以參見:

https://www.w3ctech.com/topic/2027

),淺顯易懂,非常推薦。

以上。如有謬誤,敬請指正。