打開GTA 5竟要跑19.8億次if語句!黑客嘲諷R星代碼爛,修改後直接省70%加載時間

本文經AI新媒體量子位(ID:QbitAI)授權轉載,轉載請聯繫出處
賈浩楠 發自 凹非寺

一支菸的功夫,GTA 5聯機版終於打開了。

「7年了!GTA 5聯機版加載還是這麼慢??」

Please wait forever to play

Reddit、Steam、HackerNews上,無數玩家吐槽抱怨……

進遊戲少則等5、6分鐘,多則20分鐘。

終於,一個黑客大哥實在忍不了,用逆編譯器逐條查看運行情況,終於找到原因。

原來,R星(遊戲開發商RockStar)寫的代碼太低效,加載時,一個if語句竟然循環了19.8億次….

幕後黑手:誰佔用大量時間?

加載GTA 5 Online到底有多慢?

硬件拉滿的土豪玩家請無視

Reddit相關板塊發起的調查中,超過80%的玩家,都要等3分鐘以上,有的甚至超過15分鐘。

而且,從7年前Online上線到今天,這個情況絲毫沒有改善。

暴躁的,已經罵起了髒話……

但奇怪的是,如果你選擇是故事模式(單機版),加載就會快很多,感覺甚至像兩個不同的工作室開發的遊戲。

具體到這位黑客大哥的例子,他自己的硬件配置如下:

CPU,是老而彌堅的AMD FX-8350,2012年上市,採用“推土機”架構,超頻潛力驚人。

顯卡還是GTX 1070。

這樣今天看起來老舊的配置,打開單機版GTA 5需要1分10秒,而加載聯機版則6分鐘起。

黑客大哥用了最簡單的Windows任務管理器,來判斷聯機版GTA 5在啓動時,都調用了哪些計算機資源。

在1分鐘的時間分界線上,之前是加載的是單機和聯機版通用的基礎內容,之後是聯機版獨有的內容。

可以看到,聯機版GTA 5,加載時調用大量CPU資源至少長達4分鐘之久。

而同時,內存、GPU、硬盤的使用情況幾乎沒有明顯變化。

所以,問題大概率出在代碼上。

“R星代碼寫太爛!”

黑客大哥在開扒R星代碼之前,就說:

我聞到一股爛代碼的味道…..

爲了找出到底那一部分程序卡住了CPU,他使用了工具Luke Stackwalker,對CPU任務堆棧進行採樣分析。

Luke Stackwalker對於閉源應用程序,可以轉存正在運行的進程堆棧,和當前指令指針的位置,以一定時間間隔建立一個調用樹。

最後將數據整合,就可以得到程序運行統計數據。

從結果上看,一共有兩個函數“卡住”了CPU:

於是他使用專業的代碼拆解工具,給GTA 5來了一個“開膛破肚”。

沿着調用棧往下走,發現問題出在一個sscanf函數上。

sscanf的功能是讀取格式化的字符串中的數據,而在GTA 5中,它正在讀取的是一個10M左右,有63000多個條目的JSON文件。

這個文件到底是幹什麼用的?黑客大哥推測,這可能是遊戲內購商店的相關內容。

在具體運行時,sscanf對於每個有效值,逐個讀取每一個字符,然後返回結果,之後指針移向下一個值,循環往復……直到把10M文件全部掃一遍。

再看第二個問題,這是一個存儲命令,對象是item,具體是什麼不得而知。

但是保存前,有一個if語句,逐一比較item內項目的哈希值,檢查它們是否出現在某一列表中。

按照他的計算,這一步if,要執行(63000^2+63000)/2 = 1984531500次!

沒錯,等待加載前的十多分鐘裏,GTA 5用你的CPU,執行了19.8億次if命令。

如此簡單粗暴的編程思路,讓這位老哥哭笑不得:

既然對象有唯一哈希值,那爲什麼不用hash map???

(hashmap根據hashCode值存儲數據,大多數情況下可以直接定位到它的值,因而具有很快的訪問速度,但遍歷順序不確定。

問題解決,加載時間節省70%

至於第一個問題,黑客大哥採用hook大法,不一一讀取字符串,而是:

hook strlen
“緩存 “字符串起始和當前長度。
如果在字符串範圍內函數在此被調用,返回緩存的值

至於if語句問題,就更直接了——完全跳過重複檢查,利用hash map插入項目,因爲這些值是唯一的。

最後的結果如下:

現在,GTA 5聯機版加載,從原來的6分鐘,下降到現在的1分50秒!而且,用的還是七八年前的硬件配置。

在此,應該手動@R星:你學廢了嗎?

這位黑客大哥在博文中沒有留下任何身份信息,也沒有透露用的反編譯工具,但是做好事不留名的他,把打好包的工具上傳到了Github,玩家通過一行代碼就能下載:

git clone —recurse-submodules https://github.com/tostercx/GTAO_Booster_PoC

之後,把dll文件粘貼到遊戲根目錄下就OK!

博客原文
https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/

Github地址:
https://github.com/tostercx/GTAO_Booster_PoC


       
       
       
— 【 THE END 】—
本公衆號全部博文已整理成一個目錄,請在公衆號裏回覆「 m 」獲取!


3T技術資源大放送!包括但不限於:Java、C/C++,Linux,Python,大數據,人工智能等等。在公衆號內回覆「1024」,即可免費獲取!!






本文分享自微信公衆號 - 程序員書單(CoderBooklist)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章