英特爾是如何優(yōu)化游戲性能的?
游戲已成為ChinaJoy的重要組成部分。在今年的ChinaJoy上,英特爾特別邀請了英特爾游戲合作技術經(jīng)理盧卷彬,為與會媒體們分享了很多英特爾在游戲方面的優(yōu)化措施,干貨頗多,值得大家細細品味!
本文引用地址:http://cafeforensic.com/article/202108/427264.htm英特爾游戲合作技術部門是服務客戶的團隊,需要時常跟游戲開發(fā)者一起討論很多技術問題,而現(xiàn)在的疫情對我們的團隊影響也是非常大的。作為一個全球團隊,英特爾游戲合作技術部門在歐洲、美國、中國、日本、韓國等所有在游戲開發(fā)上非常有實力的國家和地區(qū)都有團隊在負責,我們會盡可能接觸所有的游戲開發(fā)者,為他們提供技術優(yōu)化的服務。我們?nèi)椭螒蜷_發(fā)者是搞定性能問題,當然游戲好不好玩,我們能提供的幫助不多,但是我們希望能夠在性能優(yōu)化上成為客戶的依靠。為什么游戲性能很復雜?英特爾可以提供什么幫助,以及簡單的游戲優(yōu)化的方法。
這是一個最簡單的游戲架構(gòu),可以看到最下面是驅(qū)動和硬件,上面就有Graphics Runtime,包括DirectX、OpenGL或者是很多其他的中間件。再上一層就是引擎,還有最上面的游戲,每一個模塊里都有非常多的公司去提供解決方案。比如說中間的游戲引擎,像Unreal、Cryengine、Frostbite、Unity等,這里面 Unreal 和 Unity 是商業(yè)化最成功的引擎,也是大家聽得最多的,不管是手游還是 PC 游戲都在用。它們非常復雜,當中都有上百萬行的代碼,因為都是開放的,可能會有兩三百萬行的代碼,非常復雜。模塊也非常多,包括資源管理、內(nèi)存管理、角色行為、AI、圖形渲染、聲音、網(wǎng)絡、物理、UI、特效、動畫、輸入等等,非常復雜。當中的廠商很多、模塊很多、代碼巨大,游戲類型也是非常大的。比如說一個車槍球,這種游戲的玩法差別是非常大的。但是有一個好處是說,一個系統(tǒng)太復雜之后,就像人類社會一樣,我們會把它分工,每個人把自己的那一塊做大。游戲系統(tǒng)也是如此,有專門做引擎的,有專門做聲音的,有專門做物理的,有專門做渲染的等。有了這些非常專精的公司把很多內(nèi)容包裝好之后,對很多游戲開發(fā)者來說就非常容易了。其實在圖中黃線以下,就像 Unreal 的引擎,把很多內(nèi)容都已經(jīng)包裝好了,即便你只是一個開發(fā)者,你也可以使用它的引擎去開發(fā)一個還不錯的游戲,極大的方便了游戲開發(fā)者,也很大程度上推動了游戲行業(yè)的發(fā)展。對于一些大的游戲公司來說,即便是用 Unity、Unreal 等引擎仍然需要進行二次開發(fā),這時性能問題就需要你自己非常關注,因為經(jīng)過二次開發(fā),很多代碼已經(jīng)被改變,要支持這么復雜的游戲系統(tǒng),性能優(yōu)化就非常重要了,而這個時候我們就可以提供幫助。性能優(yōu)化如何去做呢?其實非常簡單,就像你怎么把大象裝到冰箱里一樣,找到問題,解決問題。這兩個問題都是非常重要的,甚至某種程度上,找到問題更重要。因為解決方案其實現(xiàn)在這個支持在互聯(lián)網(wǎng)時代大家都是共享的,你遇到任何的問題都不是你獨有的問題,在互聯(lián)網(wǎng)上會有很多人也許就這個問題進行過討論,你可以從中得到很多的啟示。在這里面,英特爾能夠提供什么幫助呢?我們說工欲善其事,必先利其器。英特爾這幾年的經(jīng)驗有相當一部分的資源就是有一整套的性能分析工具。一個負責任的性能分析工具應該是什么樣的?應該是自上而下的把程序的問題搞的清清楚楚、明明白白。英特爾 Vtune 分析工具在行業(yè)里面名氣還是響當當?shù)?,無論還是服務器還是客戶端,它可以從系統(tǒng)層面一直到每一個線程,每一個DLL,每一個函數(shù),再到每一行代碼,再到匯編都可以給你整的清清楚楚,明明白白的。這也是經(jīng)過了我們幾十年的沉淀,而且它是免費的。下面是一個非常簡單的截屏,當你用 Vtune 跑的時候,它會有一個整體概況,左邊我們可以看到,這個程序花了多長時間,對多線程的利用是多少,右邊還會去建議你下一步還可以用微架構(gòu)再跑一次,更詳細的針對微架構(gòu)的分析,或者再跑一次針對內(nèi)存的分析,可以讓你進一步了解。右邊的就是針對微架構(gòu)的分析,可以看到是前端有問題,還是在解碼有問題,還是說內(nèi)存有問題,L1、L2、L3,包括DRAM Bound各自的百分比是多少,都會給你演算出來,這是一個非常整體的概況。
上圖左下角是每個線程的概況,每個線程在每個時間點的活動是怎么樣的,線程之間有沒有一些同步關系,替代關系,都可以看得很清楚。在每一個時間段,每一個線程當中是哪些函數(shù)在運行,甚至是說每一個函數(shù)運行,再往下面直到每一行代碼都可以給你指出來,每一行代碼主要 Bound 的原因是什么,花了多長時間,都可以給你指出來。
這樣對開發(fā)者來說,就可以對程序有一個非??傮w的了解,哪一個線程是瓶頸,哪一個模塊是瓶頸,哪一個函數(shù)是瓶頸,甚至具體到哪一個代碼,真正讓你清清楚楚,明明白白,知道在哪里改進會得到最好的優(yōu)化。
在GPU上,英特爾也有一個很好的工具GPA。雖然說我們現(xiàn)在還是集成顯卡,但是未來你懂的。在過去十來年我們和客戶合作過程當中,GPA 工具也是廣受客戶贊譽的,它會對整個游戲總體的情況,具體到每一個 Pass,每一個 Draw call,每一個Shader,每一個參數(shù)都可以通過這個能夠發(fā)現(xiàn),你可以方便定位這些問題,然后讓開發(fā)者知道是什么情況。這個截屏也是一個整體的概況,從這里面可以看到它有很多的性能指標,包括你有多少個 Draw call,你每一幀的情況都能詳盡展示。當你只有一臺機器的時候,你可以像右邊這樣。左邊這個情況是說你可以連到局域網(wǎng)當中的任何一臺機器上,互不影響的收集這些信息。右邊這個是說你也可以直接切換到程序界面上,用一臺機器就可以看到這些性能信息,非常的方便。
客戶還會經(jīng)常碰到一個問題,我在玩一個游戲的時候突然掉幀,但是我不知道它是在哪掉的,我根本來不及抓取。我們還提供這樣的功能,你可以抓一段時間里面的每一幀的 Frame,抓出來之后,它可以把每一幀的時間都顯示來,然后你可以點其中最耗時的那一幀然后去播放。它從前面一直播放到這一幀就會停止,然后再把你這一幀的數(shù)據(jù)打開。比如說播放到這里就停止了,這就是最耗時的那一幀,接著把這一幀打開,你可以明顯看到你有多少個 Draw call,比如說這一幀上面有多少個 Draw call都可以看到,每一個 Draw call 的時間花費多少都顯示的非常清楚明白。
它也會對你整個這一幀有一個根據(jù)你的 3D Pipeline 來的分析。比如說右邊就是在 3D 當中,我渲染一幀要經(jīng)過哪些步驟之類的。左邊對應的我們的 GPA 就會告訴你,你在渲染這一幀的時候,其實是你的 Back-End 這邊有最明顯的問題。英特爾和游戲開發(fā)者就知道,我們怎么著手去搞定這個問題。
另外是說我可以看到每一個 Draw call 里面我用到了哪些模型,這些模型究竟有多少個頂點我都可以看得很清楚。比如說這塊石頭用了 8000 多個頂點,這樣是不是就合適呢?它耗時多長時間都會顯示出來。這段Shader代碼是什么樣的都會顯示出來。
除了工具之外,人也是非常重要的。英特爾有一些技術工程師在游戲開發(fā)的早期就會進去。另外英特爾在發(fā)布一些新的平臺的時候,我們會在測試版的機器就會給到這些開發(fā)者,讓他們提前進行適配。我剛剛也說了,我們是一個全球團隊,我們本地有一些問題能夠解決的我們就解決,不能解決的還可以把這些問題帶回給其他的團隊來幫助我們解決。國外和其他的大廠做過什么樣的優(yōu)化,有什么好的優(yōu)化方法,也可以帶回來介紹給國內(nèi)的開發(fā)者。另外我們還有測試服務,一個游戲過來,我會幫你測試你所關注的好幾個平臺上的性能。很多開發(fā)者本身也許擁有的機器是很少的,但是他想進適配或者是覆蓋的玩家設備,這個時候就可以幫到他們對大部分的平臺做性能分析或者是測試,然后反饋給他們,當你發(fā)現(xiàn)一些問題的時候,他才會有目的性的去準備一些平臺進行這種優(yōu)化。前面談到的是如何找問題,找問題是非常重要的一步。找到問題之后你如何優(yōu)化呢?這里有幾個辦法:
第一,發(fā)現(xiàn)和修正代碼。因為代碼的數(shù)量非常大,也非常復雜,尤其是一個游戲團隊當中有程序開發(fā),也有美工。你現(xiàn)在使用游戲引擎開發(fā),美工的工作量會劇增。這兩者之間可能互相之間不會相互考慮,美工考慮的是我把這個東西正確的渲染出來,但是我有沒有把一些參數(shù)設置好,一些 LOD、遮擋,以及關系到性能的參數(shù),我有沒有設計到最好?第二,并行優(yōu)化。并行優(yōu)化談了很久,它包括兩個層面,一個是多線程并行,也就是說四個車道跑總是比一個車道跑得快,并行優(yōu)化可能是優(yōu)化得到回報最高的。這當中英特爾的 TBB 可以幫助你前后線程池的調(diào)度。CPU 的多線程優(yōu)化,尤其是針對游戲相對 GPU 是非常難的。因為 GPU 就是處理幾百萬個三角形,幾百萬個頂點,它是天然的頂點和頂點之間,三角形和三角形之間是沒有依賴的,所以天然的我用幾百個或者是幾千個顯卡單元去計算,都可以得到非常線性的性能提升。但是 CPU 里面,其實它有很多邏輯,有很多模塊和模塊之間的依賴,所以就非常難。幸運的是英特爾也在和行業(yè)當中最重要的合作伙伴合作,幫助游戲開發(fā)者解決這些問題。比如說我們和 Unity 合作,做了 ECS和Job system,現(xiàn)在 Unity 對多核心的支持是非常好的。另外我們還和 Unreal做了Unreal Task system,用線程池的方式,把很多的任務可以提交到 Unreal 的任務系統(tǒng)當中,去充分應用多線程。第二個層面的并行是指令級并行,大家知道 SIMD 指令集,在一條指令里,我可以處理 8 個頂點或者是 8 個核點數(shù)。這個到開發(fā)者手中去做也是非常難的。因為你要么手工去寫一些匯編或者是寫一些 Intrinsic,你需要把 C++ 的這些算法改成 Intrinsic 這種指令集還是相對來說比較復雜的。這里面英特爾也在想辦法給大家提供一個簡單的解決方案,我們稱之為 ISPC,這是一個編輯器,它可以把你的 C 和 C++ 代碼編譯成能夠使用上,加速計算的binary,其實在 Unreal4 和 Unreal 5 當中的 ISPC 也是我們的工程師幫助他們做的。前面大家看到的 Chaos 物理破壞引擎就是使用的英特爾 ISPC 的編譯器。其實在 Unity 也有類似于 ISPC 的編譯器叫 Burst,這也是屬于在大范圍應用的。所以你是使用 Unreal 或者是 Unity 的游戲開發(fā)者,就可以非常簡單的進行一些設置和調(diào)用,就可以用上這些性能,這是我們英特爾和行業(yè)合作伙伴一起在向前推動的事情。
第三,算法優(yōu)化。這是針對具體游戲具體分析,游戲場景,游戲玩法上,哪一部分是非常突出的瓶頸,應該如何優(yōu)化它,是采用更好的數(shù)據(jù)算法還是調(diào)整我的數(shù)據(jù)結(jié)構(gòu),還是說開發(fā)者去調(diào)整場景布置之類的。這是需要游戲開發(fā)者跟我們一起來進行討論,進行頭腦風暴的一種優(yōu)化方式。
第四,底層架構(gòu)優(yōu)化。英特爾也在針對每一個工作負載去分析,它在我的CPU流水線上的表現(xiàn)。一個游戲開發(fā)者把前面的都做好了,還是覺得性能不好,他也有余力、有時間,可以進行一些底層架構(gòu)的優(yōu)化,我們英特爾的工程師也會提供建議給他們,讓他們?nèi)ピu估一下這個對我CPU代碼架構(gòu)改變有多大,會不會影響我的可維護性之類的東西,讓他們?nèi)フ遄谩?/p>
接下來分享的是英特爾在過去兩三年里,在國內(nèi)的一些游戲優(yōu)化,其中有一些是CPU相關的,有的是集成顯卡相關的??赡苡幸恍?shù)字比較夸張,因為本身我們進去的時間是比較早的,那么我們就開始用這些分析工具跟他們一起去斟酌,里面哪些是有問題,是需要去分析的。所以基本上得到這樣的結(jié)論,開發(fā)者對我們英特爾提供的幫助非常贊賞。
游戲開發(fā)者就是英特爾的客戶,客戶就是我們的上帝,我們會持續(xù)跟他們一起合作,不管是對他們未來的產(chǎn)品還是英特爾要發(fā)布的新架構(gòu)的CPU,我們都會持續(xù)在這上面進行緊密合作。
評論