IL2CPP的优化 : Devirtualization 去虚拟化
Unity的腳本虛擬機團隊一直在尋找讓代碼運行得更快的方法。這是三篇介紹關(guān)于IL2CPP AOT編譯器小優(yōu)化文章的第一篇,另外這篇文章也會教大家如何進行優(yōu)化。雖然這些優(yōu)化并不會讓你的代碼運行速度提升兩到三倍,但是它們也會對游戲起到非常重要的幫助,我們也希望它們能幫助您了解你的代碼是如何運行的。
現(xiàn)代編譯器非常擅長執(zhí)行各種優(yōu)化來提高代碼運行時的性能。作為開發(fā)人員,我們通常可以向編譯器顯式的傳達一些代碼信息來幫助編譯器提升性能。今天,我們將詳細討論IL2CPP的一個小優(yōu)化,看看它如何改進現(xiàn)有代碼的運行效率。
Devirtualization
眾所周知,虛方法的調(diào)用通常比函數(shù)直接調(diào)用開銷更大。我們對libil2cpp的運行時庫中進行了一些性能優(yōu)化,以降低虛函數(shù)的調(diào)用開銷(在下一篇文章中會有更多的介紹),但是它們?nèi)匀恍柙谶\行時進行一些查找有一些開銷。編譯器無法知道在運行時那個函數(shù)會被調(diào)用,或者是否可以被調(diào)用?
Devirtualization 是一種常見的編譯器優(yōu)化策略,它將通過虛方法通過虛表的調(diào)用轉(zhuǎn)換為直接調(diào)用。當編譯器在編譯時能夠準確地知道運行時實際會調(diào)用哪種方法時,編譯器就會使用這種策略優(yōu)化。但不幸的是,這點往往很難做到,因為編譯器通常無法了解整個代碼庫的代碼。但是如果可以做到的話,它可以使虛擬方法的調(diào)用變的更快。
典型的例子
當我作為一個年輕開發(fā)者的時候,我通過一個相當常見的動物例子學習了虛方法的相關(guān)知識。下面這段代碼您可能也很熟悉:
?
復制代碼
接下來在Unity(5.3.5版)中,我們可也以使用這些類來做一個小農(nóng)場:
?
復制代碼
這里的每次調(diào)用都是一個虛方法的調(diào)用。讓我們看看能否讓IL2CPP對這些方法調(diào)用做出優(yōu)化直接調(diào)用來提高執(zhí)行性能。
生成的C++代碼
我非常喜歡IL2CPP的一個特性就是它時生成C++代碼而不是匯編代碼。當然,這段代碼看起來不像一般手寫的C++代碼,但是還是比匯編更容易理解。讓我們看看生成的foreach里的代碼:
?
復制代碼
我已經(jīng)刪除了一些其他的生成代碼來做簡化。二手手機號轉(zhuǎn)讓看到那個丑陋的Invoke調(diào)用了嗎?它先在虛表中查找真正被調(diào)用的虛方法,然后才調(diào)用它。顯而易見,虛表的查找會比直接調(diào)用函數(shù)慢很多。因為這種動物可以是一頭牛或一頭豬,也可以是某種其他類型的動物。
接下來讓我們看看第二段代碼生成的C++代碼。第二段代碼我們new了一個Cow,然后調(diào)用了LogFormat打印Cow的Speak函數(shù)的返回值,這看上去應該是直接調(diào)用函數(shù)了吧:
復制代碼
但即使在這種情況下,我們可以看到編譯器仍然在通過虛表調(diào)用函數(shù)!IL2CPP在優(yōu)化方面相當保守,在大多數(shù)情況下都更傾向于保證正確性。由于它沒有對全程序進行分析來確定這是一個可以直接調(diào)用的函數(shù),因為可能牛也有派生類,所以它選擇了更安全(和更慢)的虛方法調(diào)用。
但是假如我們知道農(nóng)場里沒有其他種類的牛了,牛沒有其他派生類了。那么我們就可以把這些信息顯式傳達給編譯器,讓編譯器優(yōu)化,我們就能得到一個更好的結(jié)果。讓我們對Cow做一些修改:
?
復制代碼
sealed關(guān)鍵字可以告訴編譯器,Cow不會有派生類了(sealed 也可以修飾Speak函數(shù))。這樣IL2CPP就能確信可以直接進行方法調(diào)用了:
?
復制代碼
可以看到這次調(diào)用就是直接調(diào)用不會再慢了,因為我們已經(jīng)明確的告訴編譯器相關(guān)信息,可以讓編譯器進行優(yōu)化了。
雖然這種優(yōu)化可能不會讓您的游戲運行速度有顯著的提升,但是對于代碼的閱讀和編譯器本身來說,這都是一個非常好的實踐,清楚的表達您寫的代碼的意圖。如果您使用IL2CPP進行編譯,那么我強烈建議您閱讀一下編譯后生成的C++代碼,或許會有意想不到的收獲!
總結(jié)
以上是生活随笔為你收集整理的IL2CPP的优化 : Devirtualization 去虚拟化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 揭密微信《跳一跳》小游戏那些外挂
- 下一篇: 如何快速找到最优路线?深入理解游戏中寻路