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

特別說明

這是一個由 simviso 團隊對2019 Google I/O 大會中關於面向Web開發人員的WebAssembly相關話題進行翻譯的文檔,內容並不是直譯,其中有一些是譯者自身的思考。Surma是Google公司WEB基礎的貢獻者,也是open web平臺的開發倡導者。
上一篇博文地址:面向Web開發人員的WebAssembly 2019 Google I/O 上web

視頻地址:面向Web開發人員的WebAssembly 2019 Google I/O 上
視頻地址:面向Web開發人員的WebAssembly 2019 Google I/O 下
視頻同時也得到了谷歌大佬Surma和Deepti的官方推特分享和點贊
clipboard.png
1.png
視頻翻譯文字版權歸 simviso 全部
3.png
2.pngsegmentfault

前言

如今咱們來談談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中引入多線程執行的基礎。ide

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

相關文章
相關標籤/搜索