Wasm 在物聯網、雲和多媒體領域發展現狀

首屆 WebAssembly(下文簡稱 Wasm) Summit 於 2 月 10 日在美國山景城的 Google 總部順利召開。WebAssembly Summit 是由 Wasm 社區舉辦,專門討論 Wasm 當前和未來發展,以及其相關議題的全球性大會。(A one day, single track, conference about all things WebAssembly.)

《從首屆 WebAssembly Summit 看 Wasm 未來發展方向——安全性、性能和瀏覽器引擎》中,我們介紹了 WebAssembly Summit 各位嘉賓在上半場帶來的 Wasm 在標準制定、編譯優化以及瀏覽器引擎上的一些精彩分享。本文我們將繼續回顧在大會下半場中,分享者爲我們帶來的,Wasm 在現階段各類工程領域中的一些精彩實踐。

物聯網

Johnathan 爲我們帶來了 Wasm 與物聯網設備相關的實踐分享。物聯網,即 “Internet of Thing”,我們一般簡稱爲 IoT。是指相對於傳統的手機、筆記本電腦等大型設備來說的,其可使用資源有所限制(比如單核的 CPU、僅有幾百 KB 的內存和硬盤容量、有限的網絡上傳速度以及甚至只需鈕釦電池即可供電等)的小型嵌入式設備。因此相較於爲傳統普通計算機等大型設備開發軟件而言,爲嵌入式設備開發軟件則需要特殊的編程實踐方法以應對有限的軟硬件資源。

IoT 剛剛走入人們視野的最初幾年,我們一般只能通過諸如 C / C++ 甚至是彙編語言來爲這些物聯網嵌入式設備編寫軟件程序。後來,隨着互聯網技術的不斷髮展,以及從易用性、流行程度、生態系統等其他多方面的考慮,諸如 JavaScript、Lua 以及 Python 等高抽象層次的語言也被逐漸應用在嵌入式設備上,“性能”可能不再是人們選擇嵌入式設備編程語言時所需要考慮的第一要素。但現實情況是,並不是所有的嵌入式設備都可以滿足這些高抽象層次語言虛擬機在其上流暢運行的要求。並且在考慮功耗以及應用環境等情況時,它們的性能和易用性便開始捉襟見肘。而此時,Wasm 字節碼的高密度、高性能以及高可移植性使得我們有了可嘗試的新選擇。如下圖所示,通過將 Wasm 字節碼作爲多種編程語言的中間媒介,嵌入式設備使用 Wasm 虛擬機來執行字節碼,進而完成對應高級編程語言所指定的任務。通過這種方式,我們既可以利用 Wasm 的高執行效率,又不會失去可以使用高級語言的靈活性。

使用 Wasm 格式作爲 IoT 設備上多種編程語言的中間媒介

1. 運行時環境

爲在嵌入式 IoT 設備上高效執行 Wasm 字節碼,英特爾曾爲類似場景設計開發過一款專門的運行時環境,名爲 “WebAssembly Micro Runtime”,簡稱 “WAMR”。WAMR 支持 Wasm 字節碼的 AOT 和 JIT 執行,速度最快可以接近 Native;支持 X84-64、X86-32 以及 ARM 等多種平臺;更小的運行時體積和內存消耗等。WAMR 爲嵌入式設備提供了一個專門用來部署 Wasm 應用的框架環境,在這個環境中,WAMR 會統一管理所有其內部的 Wasm 應用,並提供可用的系統接口和資源。WAMR 會通過嵌入式設備上各類傳感器(計數器、傳感器、圖形控制器等)的一系列事件來驅動和響應對應的 Wasm 應用。不僅如此,WAMR 的應用程序管理器還支持通過任何物理通信(TCP、UPD 等)來從主機環境或雲進行應用的遠程管理。

當然,除了 WAMR 我們還可以使用 Wasm3 代替。Wasm3 是一個使用 C 編寫的、支持 JIT 的 Wasm 運行時環境。Wasm3 使用了特殊的優化手段來降低在解析字節碼時的性能損耗,使用了貼近硬件的寄存器模型來容納各虛擬指令對應方法的參數列表,並且通過尾遞歸來降低分支預測時的調用損耗,而這通常是一個解釋器性能好壞的決定性所在。

2.Microkernel / Unikernel

另一個比較有意思的東西是曾在 IoT 或者說嵌入式領域比較火熱的概念 ——“微內核”。如下圖所示,在左側傳統的操作系統內核架構中,有着各種各樣用來支持各類功能的底層驅動、框架、接口以及代碼庫。但實際上,對於具有某一特定功能的嵌入式設備來說,其中大部分內核底層功能都沒有存在的必要,但卻仍然佔用着硬件資源。因此是否可以只把整個硬件所需要使用的那部分底層功能單獨提取出來,使其成爲一個面向某一類特定功能或應用的專有內核。這就是“微內核”的概念。

微內核架構

相較於傳統操作系統內核,微內核有許多優勢。比如,更快的啓動速度,更小的 ROM 體積,以及更高的硬件資源使用率。而 Unikraft 便是這樣一款可以用來製作微內核的系統工具。關於 Unikraft 的更多信息,這裏不展開介紹,但需要知道的是,“微內核 + Wasm” 確實可以爲嵌入式設備帶來更高性能的任務執行環境。除此之外,Wasm 也讓嵌入式設備的各種通常由 C / C++ 實現的通訊協議的移植過程變得更加簡單。

Kevin 是來自 Capital One 的雲架構師,他爲我們帶來了 Wasm 與雲技術相結合的一些實踐。藉助於 WASI 賦予 Wasm 的能力,我們可以在 Web 平臺之外來使用 Wasm,並同時體會 Wasm 從其高性能運行時、沙盒安全性、高密度字節碼、多語言支持以及高可移植性等方面對雲技術帶來的影響。

1.waPC

“waPC” 全稱爲 “WebAssembly Procedure Calls”,同 RPC 協議類似,通過它我們可以在任意的運行時和 Wasm 模塊之間進行雙向的方法過程調用。由於現階段 Wasm 標準的限制,在諸如 Wasmtime、Wasm3 等底層 Wasm 運行時中,運行時在調用 Wasm 模塊中導出的方法時只能夠互相傳遞最基本的數值(整型、浮點型)類型數據,而 waPC 作爲一種協議便旨在解決此類問題。waPC 希望能夠獲得同 gRPC 一樣的靈活性,使得在運行時宿主和 Wasm 模塊之間的雙向通信不再需要與具體的平臺耦合。只要雙方都遵循該協議所規定的通信規範,便可以雙向地傳遞任意的有效載荷數據(比如“字符串”),並以同樣的方式從響應中獲得返回的有效載荷。

2.wascap

“wascap” 是一個針對 Wasm 模塊的子組件。設想我們需要將每一個獨立的 Wasm 模塊作爲具有獨立數據處理能力、可以提供獨立功能的一個雲服務,而通過 wascap,我們便可以爲任意的 Wasm 模塊添加、提取以及驗證對應的元數據描述清單。這裏的“元數據描述清單”是指通過 JWT 的形式被嵌入在模塊自定義段結構(Custom Sections)中的一段數據,這段數據描述了該模塊在作爲雲服務運行時所能夠使用的功能 / 服務、模塊的版本、模塊過期日期以及與安全策略相關的各類公鑰信息等。

如下圖所示,在這個示例模塊的描述清單中我們可以看到:

  • 其當前版本號爲 “v1.0.0(1)”;
  • 該模塊永遠不會過期;
  • 能夠使用的雲服務有 “K/V Store 鍵值存儲服務”“Messaging 消息服務”“HTTP 服務”等。

Wasm 模塊元數據描述清單

3.waSCC

“waSCC” 的全稱爲 “WebAssembly Secure Capabilities Connector”,顧名思義,通過 waSCC 我們可以將上述介紹的兩個概念連接(Connect)起來。waSCC 是基於 waPC 構建的,內部使用 Wasmtime 來作爲 Wasm 模塊的底層運行時環境。當我們將一個 Wasm 模塊部署在 waSCC 上時,waSCC 會啓動獨立的進程爲該 Wasm 模塊提供服務,同時它會根據 wascap 對模塊內部 JWT 元數據描述清單的解析結果,來爲模塊提供相應的外部能力。比如常見的諸如 “wascc:http_server” 對應的 HTTP 服務與 “wascc:keyvalue” 對應的鍵值存儲服務等。這裏 waSCC 會使用命名空間 “wascc” 前綴來區分模塊可以使用的外部能力是否是由 waSCC 本身提供的。那除了這些“原生”能力以外,waSCC 還可以爲 Wasm 模塊提供由 “.so” 原生共享庫(通過 C-FFI 調用)提供的能力,以及其他被部署在 waSCC 上的 Wasm 模塊提供的,基於 WASI 構建出的能力。

回過頭來看,傳統我們在構建大規模雲服務時,通常會使用容器技術來隔離各個功能提供商(Provider)的運行時環境以進行資源的隔離與功能的動態替換。但此時,藉助於 Wasm 本身的沙盒特性,使得每一個被部署在 waSCC 上的 Wasm 模塊都只能夠使用自己有限的資源,並在有限的上下文中運行。而這相對於傳統的容器技術來說,無疑大幅降低了部署雲服務的成本,且功能模塊更加輕量並易於管理。想到最近一段時間正在被各大互聯網公司調研的 Wasm 與 FaaS 相結合的嘗試,不知道會不會引起你更多的思考?

多媒體

Brion 是維基媒體基金會(Wikimedia Foundation)的一名軟件架構師,他爲我們帶來了維基百科網站爲支持“視頻播放能力”所歷經的一系列探索與實踐。在網站建設的初期,維基百科曾經歷了從使用 GIF 圖片、Java Applet、瀏覽器插件再到 Flash 的一系列變革。而直到 Emscripten 的出現,才爲“多瀏覽器兼容的高效視頻播放”這一需求提供了轉機,ogv.js 便誕生於此。

ogv.js 是一個可以在瀏覽器中使用的多媒體播放器。下圖爲其整體的設計架構,其中 Demuxer 作爲核心組件主要用於解碼並提取各類型媒體文件中的音視頻內容,因此,這部分計算邏輯較多的工作便交由 Wasm 來進行加速。不僅如此,ogv.js 還可以同時利用瀏覽器支持的“多核心(Multi Cores)Worker”特性來對整個解碼過程進行加速。與此同時,隨着 Wasm 最新的 SIMD 標準被越來越多的瀏覽器實現,ogv.js 在處理視頻像素矩陣以及各類相關編解碼工作時,還可以利用該特性來進一步加速。不得不提到的是,2019 年 Wasm 的一個最重要的實踐應用領域便是音視頻處理領域。

ogv.js 設計架構

電子音樂

除了上述我們介紹的,Wasm 在幾個比較值得關注的工程領域內的實踐外,作爲一個會寫代碼的音樂家,來自挪威的 Peter 還爲我們帶來了他使用 Wasm 技術在實時音樂創作上的一些嘗試。基於 AssemblyScript(下文簡稱 AS)編寫的合成器(Synthesizer)可以被直接轉換成對應的 Wasm 格式,並在瀏覽器中運行。藉助 Wasm 格式在瀏覽器中相較 JavaScript 更高的執行效率,因此可以爲在線的實時音樂創作提供一個低延遲、高幀率的解析與播放環境。

通常來說,合成器主要用來產生具有不同音色的聲音,然後再配合音序器(Sequencer)來根據特定的“曲譜”生成帶有不同節奏、速度以及力度的音樂片段。這其中,合成器的發聲主要依靠對各種常見震盪波形(比如正弦波、鋸齒波以及方波等)進行疊加和處理,然後再經過放大器放大輸出,那這裏大部分平臺相關的工作主要依賴於對應的 Web Audio API 來實現。因此,“對各類波形進行數字化處理”這個過程便是整個合成器的最主要工作。如果我們能夠將這部分純計算邏輯的任務交給 Wasm 來處理,那麼整個合成器的性能便會得到極大的提升。

基於 Wasm 加速的在線音樂創作器

不僅如此,一個有趣的地方是,我們還可以將創作好的音樂片段下載成以 “.wasm” 爲後綴結尾的標準 Wasm 模塊文件。該模塊在被虛擬機執行時將會導出對應到 RAW 格式的標準二進制數據。此時,我們便可以配合諸如 SoX 等音頻處理程序來對這些數據進行處理,比如以音頻的形式直接播放出來,或者轉換成其他標準格式的音頻文件。

AS 作爲一個 TypeScript(下文簡稱 TS)到 WebAssembly 編譯器,它給想要快速體驗 Wasm 的前端開發同學提供了一個可以快速上手的途徑。與 TS 類似,爲了直接對應到 Wasm 標準中的數據類型,使用 AS 開發時需要將傳統 TS 中諸如 “number” 等類型註釋替換爲 “i32”“u64” 等更爲具體的子類型。但與此同時,由於 JavaScript 語言本身的一些特性以及現階段 Wasm MVP 標準上的限制,使得 AS 在處理 TS 中諸如閉包、異常處理以及 OOP 等相關代碼時的能力還不完善,因此這部分代碼可能無法被正常編譯到對應的 Wasm 字節碼中。但總體而言,AS 作爲貫穿整個大會的重要角色,在現階段也是作爲生態中主要的編譯工具之一,還是值得我們去嘗試的。

發展和現狀

Ben 作爲 WebAssembly Working Group 的主席,帶領我們回顧了 Wasm 從其出生,到 MVP 標準被四大瀏覽器實現,再到 WASI 的出現,以及 Post-MVP 標準不斷制定的這五年時間裏 Wasm 在各個重要節點發生的變化。Wasm 項目啓動於 2015 年的 5 月,當時對應的 WAT 規範被稱爲 “ml-proto”,對應的字節碼規範則被稱爲 “v8-native-prototype”。Ben 作爲 Google 員工便接下了編寫從 ml-proto 可讀文本到 v8-native-prototype 字節碼轉換工具的任務,這個工具在當時被稱爲 “sexpr-wasm”,即現在的 WABT。該工具的第一個版本,是 Ben 在當時花了兩週時間完成的。從下圖可以看到 Ben 在當時編寫 sexpr-wasm 時,在各個功能組件階段所花費的時間,以及對應每天提交的 Commit 數量。

sexpr-wasm 初期開發進度

“APIE” 是由四個單詞 “Ability”“Producer”“Interop”“Embedder” 組成,這四個單詞分別從四個不同的角度分別描述了 Wasm 的發展程度,即:

  • Wasm 能夠做什麼(能力)?
  • 誰可以生成 Wasm(生產者)?
  • Wasm 可以和誰進行互操作(交互)?
  • 誰可以使用 Wasm(平臺)?

2017 年,Wasm 取得了四大瀏覽器 Chrome、Edge、Firefox 以及 Webkit 對其 MVP 標準的一致性支持。這一年 Wasm 標準開始加入 GC 與 Host Binding 提案以增強其與平臺之間的互操作性;2018 年,Wasm 生態加入了 Reference Types 和 Wasm C API 提案,開始將 GC 這個棘手的難題分解成若干相關的子提案以快速推進 Wasm 的發展。而 Wasm C API 的出現則爲各類平臺方便使用 Wasm 提供了幫助。2019 年,這一年的 Wasm 生態又加入了很多新的成員,WASI 的出現又進一步提高了 Wasm 與平臺之間的互操作性,使得其 out-of-web 成爲可能;Type Function Reference 與 Type Imports 提案的出現也進一步推動了 GC 的最終實現。

截至 2019 年 8 月所有開放的 Wasm 提案

後記

自筆者 2017 年接觸 Wasm 至今,其發展速度着實超過了任何一個其他類似的 W3C 標準化組織。從 MVP 標準的落地,到 WWG 的成立,再到全球第一次 WebAssembly Summit 的成功舉辦,彷彿又映射了 Atwood 的那句名言:“任何可以使用 JavaScript 來編寫的應用,最終都會由 JavaScript 編寫”,只不過這次的主角變成了 Wasm。當然我們都知道這只是這只是一句玩笑話,但也確實從側面反映出來 JavaScript 如日中天的這樣一個時代。經過了將近五年的發展,Wasm 逐漸在國外技術社區掀起新一輪的技術浪潮,隨之而來的是衆多的虛擬機、編譯器以及各類配套的底層工具鏈如雨後春筍般涌現。

通過這次的 Wasm Summit 我們發現,Wasm 已經逐漸開始在應用層面顯示出它的能力,並逐漸開始向雲技術、物聯網以及區塊鏈等多個重要領域發起“進攻”。最後,讓我們一同拭目以待,未來的 Wasm 能夠引領新一輪的互聯網技術變革。也同時祝願我們能夠在 2020 年成功爲大家帶來中國的 WebAssembly Summit China 峯會,期待與你屆時的相遇。

作者簡介:

於航,曾在阿里巴巴本地生活、Tapatalk 等國內外企業工作,現在 PayPal 上海負責 GRC 相關的技術研發工作;FCC (FreeCodeCamp China) 上海技術社區負責人;多次 QCon、GMTC 大會講師;WebAssembly 技術佈道者;2018 年出版名爲《深入淺出 WebAssembly》的國內第一本 Wasm 技術書籍;2019 年開發名爲 TWVM 的輕量級 Wasm 虛擬機。主要研究領域爲:前端基礎技術架構、 Serverless、WebAssembly、LLVM 及編譯器等相關方向。

GMTC 全球大前端技術大會(北京站)2020,於航老師擔任“前端前沿技術”出品人,也將邀請行業內知名技術專家現場爲大家分享更多新興技術。欲瞭解更多前端前沿技術趨勢,請點擊官網

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章