[譯][A crash course in WebAssembly] WebAssembly的進度和計劃

Yiniau發表於2018-03-24

title: [A crash course in WebAssembly] WebAssembly的進度和計劃

date: 2018-3-24 10:26:00

categories: 翻譯

tags: WebAssembly

source: 原文地址

auther: Lin Clark


[A carsh course to WebAssembly] WebAssembly 進度與計劃


這是WebAssembly系列文章的第六部分。如果您還沒有閱讀其他文章,我們建議您從頭開始

2月28日,四大主流瀏覽器宣佈他們一致認為WebAssembly的MVP已經完成。這提供了瀏覽器可以開始釋出的穩定的初始版本。

[譯][A crash course in WebAssembly] WebAssembly的進度和計劃

這為瀏覽器提供了一個穩定的核心。此核心不包含社群組正在計劃的所有功能,但它確實提供了足夠的功能來確保WebAssembly快速且可用。

藉此,開發人員可以開始釋出WebAssembly程式碼。對於較早版本的瀏覽器,開發人員可以傳送一個asm.js版本的程式碼。因為asm.js是JavaScript的子集,所以任何JS引擎都可以執行它。通過Emscripten,你可以將相同的應用程式編譯為WebAssembly和asm.js。

或者學習Rust,通過 LLVM toolchain 編譯到 .wasm 檔案。

即使是較早的版本,WebAssembly依舊能體現效能優勢。通過修復和新增新功能,未來效能會進一步提升。

提升 WebAssembly 在瀏覽器中的效能

隨著瀏覽器在其引擎中改進對WebAssembly的支援,效能將逐漸提升。瀏覽器供應正在各自獨立處理這些問題。

JS 與 WebAssembly之間更快的呼叫

目前,在JS程式碼中呼叫WebAssembly函式比預期的慢。那是因為它必須做一些叫做“trampolining”的事情。 JIT不知道如何直接處理WebAssembly,所以它必須將WebAssembly傳送可以處理它的東西。這是段引擎本身的慢速程式碼,它被設定為執行優化的WebAssembly程式碼。

[譯][A crash course in WebAssembly] WebAssembly的進度和計劃

如果JIT知道如何直接處理它,這將會快100倍!!。

你或許不會在傳遞一個大型任務的時候察覺到差別,但如果有許多的JS - WebAssembly之間的互相操作,效能差異就會格外明顯(就像傳遞一大堆小任務的時候,每個任務都會經歷這個過程)。

更快的載入

JIT必須在載入時間和執行時間之間作出權衡。如果您提前花更多時間進行編譯和優化,這會就會加快執行速度,同時減慢啟動速度。

有很多正在進行的工作來平衡預編譯(確保程式碼開始執行後不會出現跳動)並且事實上,大部分程式碼不會有進行優化編譯所需的足夠多的執行時間。

由於WebAssembly不需要推測型別,因此引擎不必在執行時監視型別。這給了他們更多選擇,例如將編譯工作和執行並行化。

另外,最近增加的JavaScript API將允許流式編譯WebAssembly。這意味著引擎可以在一邊下載一邊編譯。

在Firefox中,我們正在研究一個雙編譯器系統。 其中一個編譯器會提前執行,並且擅長優化程式碼。另一個編譯器會在執行程式碼時在後臺執行完全優化。程式碼的完全優化版將在其準備就緒時與正在執行的程式碼切換。

為規範新增post-MVP功能

WebAssembly的目標之一是在指定的一個小塊中進行測試,而不是事先設計好所有的東西。

這意味著有很多預期的功能,但還沒有全部經過完備的思考。它們將不得不經歷所有瀏覽器供應商都積極參與的規範流程。

這些功能稱為未來功能。這裡列出了一小部分

Working directly with the DOM

目前還沒有辦法與DOM直接進行互動。這意味著你不能像element.innerHTML那樣通過WebAssembly更新一個節點。

作為代替,你必須通過JS來設定值。這可能意味著將值傳遞迴JavaScript呼叫方。另一方面,它可能意味著在WebAssembly中呼叫JavaScript函式 ———— JavaScript和WebAssembly函式都可以作為匯入的資源在WebAssembly模組中使用。

[譯][A crash course in WebAssembly] WebAssembly的進度和計劃

無論哪種方式,通過JavaScript訪問的速度可能比直接訪問慢。某些使用WebAssembly的應用程式可能會被妨礙,直到問題被解決。

共享記憶體併發 Shared memory concurrency

加速程式碼執行的一種方法是使程式碼的不同部分能夠並行執行。然而,這有時會適得其反,因為執行緒之間的通訊開銷可能比任務花費更多的時間。

但是如果可以線上程之間共享記憶體,這種開銷在一定程度上會減少。為此,WebAssembly將使用JavaScript的新的SharedArrayBuffer。一旦在瀏覽器就緒,工作組就可以開始規範WebAssembly如何與它們配合使用。

SIMD

如果你閱讀過其他文章或參與過關於WebAssembly的討論,您可能會聽說過SIMD。這個縮寫代表單指令,多資料。這是另一種並行執行的方式。

SIMD使得獲取龐大的資料結構成為可能,如不同數字的向量,並將同一條指令同時應用於不同的部分。通過這種方式,它可以極大地加速遊戲或VR所需的複雜計算。

這對普通的Web應用程式開發人員來說並不重要。但對於遊戲開發人員這樣使用多媒體的開發人員來說,這非常重要。

異常處理

像 C++ 這樣的語言的許多程式碼庫都使用異常。但是,異常尚未被指定為WebAssembly的一部分。

如果您使用Emscripten編譯程式碼,它將模擬某些編譯器優化級別的異常處理。但是,這很慢,所以你可能想使用DISABLE_EXCEPTION_CATCHING標誌來關閉它。

如果異常在原生WebAssembly中得到處理,這種模擬將不是必需的。

其他改進 - 為開發人員提供服務

一些未來的功能在不影響效能的前提下,能夠使開發人員更輕鬆地使用WebAssembly。

  • First-class source-level developer tools. - 一流的原始碼級開發人員工具 - 目前,在瀏覽器中除錯WebAssembly就像除錯原始彙編。只有一丟丟開發人員可以在心中將其原始碼對映到彙編(人形編譯器嗎??)。我們正在研究如何改進工具支援,以便開發人員可以除錯他們的原始碼。

  • Garbage collection - 垃圾回收 - 如果你可以提前定義型別,就應該能夠將你的程式碼轉換為WebAssembly。所以使用類似TypeScript的程式碼應該也可以編譯為WebAssembly。但是,目前唯一的困難是WebAssembly不知道如何與現有的垃圾收集器進行互動,比如內建於JS引擎的垃圾收集器。這個未來功能的想法是通過一系列底層GC的原始型別和操作為WebAssembly提供對內建GC的頂級訪問。

  • ES6 module integration - ES6模組整合 - 瀏覽器目前正在使用指令碼標籤()新增對載入JavaScript模組的支援。新增此功能後,即使url指向WebAssembly模組,標籤(如

相關文章