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