「2019 Google I/O 大會」面向Web開發人員的WebAssembly (下)

特別說明

這是一個由 simviso 團隊對2019 Google I/O 大會中關於面向Web開發人員的WebAssembly相關話題進行翻譯的文檔,內容並非直譯,其中有一些是譯者自身的思考。Surma是Google公司WEB基礎的貢獻者,也是open web平臺的開發倡導者。
視頻地址:面向Web開發人員的WebAssembly 2019 Google I/O 下
視頻同時也獲得了谷歌大佬Deepti的官方推特點贊
1.png
視頻翻譯文字版權歸 simviso 所有
3.png
2.png

前言

現在我們來談談WebAssembly的未來和即將到來的未來。歡迎Deepti上臺發言。

謝謝,Surma。

Hi,各位,我叫Deepti。我是Chrome團隊的軟件工程師,我致力於標準化 WebAssembly 功能,並在V8中實現它們。

到目前爲止,你在本演講中所看到的大部分內容都已經在所有主要瀏覽器中落地實現了。也可以說這是MVP或者說是WebAssembly的最小可行性產品。(譯者注:MVP(Minimum Viable Product –最簡化可實性產品)是一種在創業團隊中非常流行和實用的產品理念,旨在通過提供最小化可行產品獲取用戶反饋,並在這個最小化可行產品上持續快速迭代,直到產品到達一個相對穩定的階段。)

並且,我們一直在努力增加功能,以確保我們越來越接近本地性能。這個MVP本身就是打破了Web平臺的限制,可以在它之上運行的一整套新的應用程序。但這不是最終目標,社區組織和實現者正在努力實現很多令人興奮的新功能。

WebAssembly多線程提案

其中第一個就是WebAssembly 多線程提案。多線程提案引入了並行計算。
4.png
具體的說,這意味着它引入了線程之間共享線性內存的概念,以及原子指令的語義。現在,爲什麼有必要這麼做?

有許多用C或C ++編寫的現有庫使用了Pthreads(POSIX線程(POSIX threads)),它們可以編譯成wasm,並且以多線程模式運行,允許不同線程並行處理相同的數據。除了啓用新功能外,對於受益於多線程執行的應用程序,你會看到性能隨着線程數的增加而增長。因此,這個線程提案是建立在Web平臺中已經支持多線程的基礎之上。
5.png
Web 已經支持使用Web Workers來進行多線程執行,這剛好可以用來作爲在WebAssembly中引入多線程執行的基礎。

Web Workers的缺點是他們之間不能共享可變數據。反而,他們依賴消息傳遞,通過發送消息進行通信。因此它們通過消息傳遞進行通信。所以每一個WebAssembly線程都在一個Web Worker中運行。

但是它們共享了WebAssembly 內存允許他們處理相同的數據。使它們的運行速度接近於本地速度。

這裏的共享線性內存建立在JS共享數組Buffer上。

因此,如果你看這幅圖,發現它們每個線程都運行在一個Web Worker中,並且使用一樣的線性存儲實例化一個WebAssembly 實例。

這意味着這些線程實例的操作可以在共享內存上進行,但各自都有它們自己的獨立執行堆棧。因此,用於創建WebAssembly 內存的API幾乎保持不變。
6.png
如果你看到圖中第一行代碼,你創建一個包含 shared 和 maximum 參數的WebAssembly 內存。這將在下面創建一個共享數組Buffer,其中 initial (初始)大小是由我們指定的,即一頁內存。

因此,這些線程都在同一個內存上操作,我們怎麼確保數據是一致的?

原子修改允許我們執行某種級別的同步。所以,當一個線程執行原子操作時,其他線程在它發生的瞬間會立即看到。但實際上完全同步的操作往往會阻塞一個線程,直到其他線程完成執行。

所以這個提案有一個互斥實現的例子,並且我介紹瞭如何通過JavaScript使用它。

如果你仔細觀察,你會發現你在工作中所做的與在主線程上所做的之間所存在微妙的差異。

因此,在主線程上調用 tryLockMutex 方法,該方法嘗試在給定address上添加一把互斥鎖 。如果互斥鎖鎖定成功,則返回1,否則返回0。在工作線程上,它會在給定地址進行互斥鎖的鎖定,重試直到鎖定成功。所以基本在Web上就是通過這樣一種方式來構建的(線程模型)。

實際上你不能阻塞主線程。這是我們在使用線程過程中需要記住的,這很有用。那麼該提案 現在處於一個什麼狀態?該提案一直在穩定推進中。

當下正在進行的工作是確定共享數據Buffer使用的內存模型。
7.png
真正讓我興奮的是它已經在 Chrome 74中進行提供,默認情況下是啓用狀態。Surma 在之前的演講中提到了QT,並且QT有完整的線程支持,因此你可以在你的應用程序中基於多線程使用它。對於此處來說,這裏的共享內存使用的是JavaScript 下的共享數組Buffer。但在某些瀏覽器上是臨時禁用的。

默認情況下,所有瀏覽器上的WebAssembly多線程目前都無法使用。但你仍然可以在Firefox Nightly版上試試這個。
8.png
WebAssembly 的目標之一是對現代硬件進行低級抽象。對於 WebAssembly SIMD 提案更是如此。

SIMD 是一個單指令多數據流。它允許一條指令同時操作多個數據項。因此,大多數現代CPU都支持矢量運算的某些子集。因此,該提案正嘗試利用你每天使用的硬件中已經存在的功能。

這裏的挑戰是找到一個在大多數架構中都能得到良好支持的子集,但仍在尋找過程中。

目前,該子集僅限於128位SIMD。有兩種不同方式去使用SIMD提案。

通過使用自動矢量化,你可以在編譯時傳入一個標誌位來啓用SIMD,並且編譯器會自動識別你的程序。

另一方面,很多SIMD用例都比較小衆,即爲了高度專注性能使用手動編寫assembly。

所以,這些將會使用Clang內置或內聯函數生成針對性能調優的機器碼。(譯者注:Clang是一個C語言、C++、Objective-C語言的輕量級編譯器)

現在,SIMD可用於各種各樣的應用程序。所以你可以用它來製作圖像或音頻,視頻編解碼器,像Google Earth和Photoshop這樣的應用程序,甚至是Web上的機器學習應用程序。

WebML與SIMD

我們對WebML(Web建模語言)和SIMD的協作也很感興趣。

那麼讓我們來仔細看看這些數據是如何運作的。
9.png
在這裏,你可以看到一個關於數組add指令的簡單示例。

假設這是一個Integer類型的數組,在左側,看起來像是標量運算,將每個數字與另一個數字相加並存儲結果。這個矢量版本只能歸結爲一條硬件指令。(譯者注:從圖中可以看到有箭頭方向)例如,在一些Intel架構上的一個p AD或一個vp AD 操作。

因此,SIMD操作通過允許將多塊數據打包到一個數據域中來工作,並且使指令能夠作用於每個數據塊。

這對於必須對大量數據執行相同操作的情況很有用。

例如,圖片處理。如果你想在Squoosh中壓縮圖片,或者將Photoshop 中圖片的色彩降低一半。實際上,SIMD操作在做這些事情時性能會更高。
10.png
我們已經討論了關於利用底層硬件功能來提升OA辦公應用程序的性能。現在,讓我們來看看另一方面會發生什麼。那麼我們該如何更好地與主機交互呢?

引用類型提案

其中一個提議是引用類型提案,由多個瀏覽器實現。對於引用類型提案,WebAssembly 代碼可以使用ref值類型傳遞任意的JavaScript 值。這些值對WebAssembly不具備透明性,但通過導入JavaScript 內置函數,WebAssembly 模塊可以執行許多基本的JavaScript 操作,而無須本來需要的JavaScript 膠水代碼。

所以,WebAssembly 表對象是一個高級別存儲函數引用的結構。所以這個引用類型提議也添加了一些用於操作wasm內表的表指令。關於這一點的巧妙之處在於,引用類型提案實際上爲未來真正有用的提案奠定了基礎。

基於此,可以通過Web IDL(接口定義語言)提案更高效的與本地主機進行交互操作或者異常引用的處理。同時它還可以實現更平滑的垃圾回收路徑,我將在接下來的幾張幻燈片中討論這些。

WebIDL綁定提案

因此,我們團隊在不久的將來會側重於一個Web IDL綁定提案(譯者注:後面有圖,一看便知)

Web IDL 是一個接口定義語言,它可以用來定義在Web中實現的接口。

我們通過引用類型來稍微談下這個,這裏的基本思路是,該提案描述了向WebAssembly 添加一個新機制,爲了避免在調用或者通過調用Web IDL接口時產生不必要的開銷。

Web IDL 提案將會允許編譯器優化從WebAssembly到現有的Web API和瀏覽器環境以及未來可能會用Web IDL 的其他API的調用。

讓我們仔細看下這張圖。

11.png
當你有一個wasm函數時,你將會通過JS API調用JavaScript 。

JS API通過綁定層來促成JS API與用於Dom訪問的Web API之間的通信,這裏增加了許多膠水代碼和額外開銷。

Web IDL綁定提案的目標就是減少這種開銷,並優化從WebAssembly到現有的Web API的調用。
12.png
所以實際上,這裏不需要通過JS API,並且綁定也將被優化用以減少開銷。
13.gif
因此,你可以精簡WebAssembly 和 Web API之間調用。

目前,我們談到了C,C++,Rust,將這些語言放到WebAssembly 上時,都得到了非常好的支持。而且有很多工作會不斷地需要將不同種類的其他語言引入Web中來。

WebAssembly的發展與未來

14.png
一旦對支持高級語言必須的垃圾回收功能得以實現,也就意味着更快的執行,更小的模塊。

除C,C++之外,這實際上能夠支持大多數現代語言的要求。

當然,這也是個巨大的開放性問題。但是我們一直通過制定較小的提案並進行精確的設計約束磨練探索,以此來取得進展。

因此,目前,wasm被明確地設計用於位尾調用優化。將來,我們希望爲需要尾調用仿真(系統API,參考前面的分享)的語言啓用正確有效的尾調用實現。

所以這些就像是Haskell這樣的函數式語言。

V8已經實現了這個,並且進展得十分順利。因此,對於完整的C++支持,我們需要異常處理。

在Web環境中,異常處理可以使用JavaScript進行模擬。

JavaScript可以爲異常處理提供正確的語義,但它的確不快。

因此發佈MVP後,WebAssembly 將會獲得0成本的異常處理支持,這也是我們正在努力做的事。

我們也在研究一些其他提案,所以請隨時查看在 WebAssembly GitHub頁面上的未來特性文檔。

我要強調的另一件事就是其中有很多都還在設計階段,如果你有興趣參與,所有的開發都是在一個開放的社區小組中完成的,因此,隨時歡迎貢獻。

我們也會討論性能。如果你有性能瓶頸,並且使用了wasm 去提升了其中一些我們所關注的點,我們會很高興聽取你的意見。

好了,Surma和我就講到這裏。之後我們會在Web Sandbox繼續。因此,如果你有問題,請過來找我們或者在網上找我們。

聯繫我們

歡迎加羣和我們交流
16.png
如果感興趣可以關注我們的微信公衆號
17.png

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