Javascript是如何工作的:V8引擎的核心Ignition和TurboFan

spursyy發表於2018-03-15

文章翻譯自V8團隊系列部落格中Launching Ignition and TurboFan

今天我懷著無比激動的心情宣佈V8執行Javascript的管道5.9版將會與Chrome的M59同步。最新版的執行管道將會為Javascript帶來顯著的效能和記憶體佔用的優化。關於更多效能優化資料我們會在文末有大量的論述,首先讓我們認識下Ignition和TurboFan。

Ignition.png
TurboFan.png

新的管道是由V8的直譯器(Ignition)和V8編譯器(TurboFan)組成。這些技術對於在這些年一直專注V8部落格的開發者並不感到陌生,但是V8引擎切換新的管道體系卻有著里程碑的意義。

Ignition和TurboFan第一次用來執行Javascript是從V8 5.9開始的。這也意味著自2010後一直服務V8引擎的Full-codegen和Crankshaft將不在使用。它們不能滿足Javascript每年推陳出新變化趨勢和優化這些新特性的需求。我們也將計劃將它們完全從V8技術體系中清除,V8引擎將會朝著越來越簡單、易控制方向發展。

漫長的旅途

V8引擎團隊在優化真實生產環境下Javascript的效能和評估Full-codegen、Crankshaft的優劣做了大量細緻的工作。融合Ignition和TurboFan的開發工作已經進行了三年半,這將是我們在未來繼續優化執行Javascript效能的基礎。

TurboFan在2013發起初只是為了彌補Crankshaft僅僅可以優化Javascript一部分語言的短板。例如,它並沒有通過結構化的異常處理來設計程式碼,即程式碼塊並沒有通過try、catch、finally等關鍵字劃分。另外由於為每一個新的特性Cranksshaft都將要做九套不同的框架程式碼適應不同的平臺,因此在適配新的Javascript語言特性也很困難。還有Crankshaft框架程式碼的設計也限制優化機器碼的擴充套件。儘管V8引擎團隊為每一套晶片架構維護超過一萬行程式碼,Crankshaft也不過為Javascript擠出一點點效能。

TurboFan在起初設計的時不僅是為了適配ES5標準的特性,同時也是為了優化ES2015及以後的規範的新語言特性。在TurboFan通過清楚區分高質量和低質量優化編譯的分層編譯器,實現在不修改架構程式碼的情況下優化新的語言特性。同時由於在TurboFan增加明確的指令選擇編譯階段,可以為每個支援的平臺編寫少得多的體系結構程式碼。在這個新的階段中,體系結構程式碼只需要編寫一次,而且很少需要更改。這些變化為V8提供了更容易維護和可擴充套件的優化編譯器。

Ignition設計之初是為了減少移動裝置的記憶體佔用。以前通過Full-codegen基準編譯器生成的程式碼幾乎要佔用Chrome瀏覽器三分之一的堆記憶體。這樣為應用的實際資料留下的記憶體空間就很少。當在限制RAM的Android裝置上啟用Chrome M53的Ignition時,未優化的基準Javascript程式碼在ARM64的移動裝置上的記憶體佔用下降了九倍。

後來V8團隊利用Ignition和TurboFan合作生成並優化的機器碼而不是像Crankshaft重複編譯原始碼,來提高V8效能。Ignition的位元組碼為V8引擎提供了一種更簡潔、更少錯誤的基準執行模型,大大簡化V8的自適應優化的去優化機制這一關鍵特性。最終,由於產生位元組碼的速度要遠遠快於產生Full-codegen的基準編譯程式碼,啟用Ignition通常可以改善程式碼的啟動速度和網頁的載入速度。

從整體架構上Ignition與TurboFan在一起配合工作有許多的好處。例如,不需要在手工編寫高效的程式集處理Ignition生成的位元組碼,而是使用TurboFan中介軟體來處理,並讓TurboFan為V8所支援的平臺進行優化和生成最終的執行程式碼。

執行表現

拋開歷史,讓我們看看真實生產環境下新管道技術的表現。

V8團隊過去一直在使用Telemetry-Catapult作為測試效能的框架。在上一篇文章中我們已經討論關於通過真實生產環境的測試資料驅動效能優化的重要性和如何使用WebPageReplay與Telemetry結合採集測試。

Reduction in time spent in V8 for user interaction benchmarks.png

雖然Speedometer是一個綜合標準,我們之前也沒發現其它綜合測試標準可以比它更準確描述現代Javascript在真實環境中效能。在管道技術切換到Ignition和TurboFan後,Speedometer的綜合指標在不同的平臺略微有些差異,但是整體上提高了5-10%。

benchmarkscores.Improvements on Web and Node.js benchmarks .png

與此同時Ignition和TurboFan也減少了V8整體的記憶體佔用。在M59版的Chrome瀏覽器中,新的管道技術可以為桌面端和移動端減少5-10%不等的記憶體佔用。Ignition記憶體佔用的減少最總導致V8整體記憶體佔用的優化,這一方面我在之前的文章中有所涉獵。

這些效能上的改善都只是開始,Ignition和TurboFan組成的新的管道技術為執行Javascript的效能優化普平了道路,V8的記憶體無論在Chrome還是在Node.js都將會大幅降低。我們期待與你分享這些改進。

相關文章