您現在的位置是:首頁 > 音樂首頁音樂

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

由 量子位 發表于 音樂2021-07-19
簡介可以看到,聯機版GTA 5,載入時呼叫大量CPU資源至少長達4分鐘之久

gta4遊戲根目錄在哪裡

賈浩楠 發自 凹非寺

量子位 報道 | 公眾號 QbitAI

一支菸的功夫,

GTA 5聯機版

終於打開了。

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

Please wait forever to play

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

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

終於,一個駭客大哥實在忍不了,用逆編譯器逐條檢視執行情況,終於找到原因。

原來,R星

(遊戲開發商RockStar)

寫的程式碼太低效,載入時,一個if語句竟然迴圈了19。8億次…。

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

載入GTA 5 Online到底有多慢?

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

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

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

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

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

但奇怪的是,如果你選擇是故事模式

(單機版)

,載入就會快很多,感覺甚至像兩個不同的工作室開發的遊戲。

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

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

顯示卡還是GTX 1070。

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

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

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

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

而同時,記憶體、GPU、硬碟的使用情況幾乎沒有明顯變化。

所以,問題大機率出在程式碼上。

“R星程式碼寫太爛!”

駭客大哥在開扒R星程式碼之前,就說:

我聞到一股爛程式碼的味道…。。

為了找出到底那一部分程式卡住了CPU,他使用了工具

Luke Stackwalker

,對CPU任務堆疊進行取樣分析。

Luke Stackwalker對於閉源應用程式,可以轉存正在執行的程序堆疊,和當前指令指標的位置,以一定時間間隔建立一個呼叫樹。

最後將資料整合,就可以得到程式執行統計資料。

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

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

沿著呼叫棧往下走,發現問題出在一個

sskanf

函式上。

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

sskanf的功能是讀取格式化的字串中的資料,而在GTA 5中,它正在讀取的是一個10M左右,有63000多個條目的JSON檔案。

這個檔案到底是幹什麼用的?駭客大哥推測,這可能是

遊戲內購商店的相關內容。

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

在具體執行時,sskanf對於每個有效值,逐個讀取每一個字元,然後返回結果,之後指標移向下一個值,迴圈往復……直到把10M檔案全部掃一遍。

再看第二個問題,這是一個儲存命令,物件是

item

,具體是什麼不得而知。

但是儲存前,有一個if語句,逐一比較item內專案的雜湊值,檢查它們是否出現在某一列表中。

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

1984531500

次!

沒錯,等待載入前的十多分鐘裡,GTA 5用你的CPU,執行了19。8億次if命令。

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

既然物件有唯一雜湊值,那為什麼不用

hash map

???

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

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

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

hook strlen

“快取 “字串起始和當前長度。

如果在字串範圍內函式在此被呼叫,返回快取的值

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

最後的結果如下:

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

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

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

GTA5要跑19.8億次if!駭客修改後直接省70%載入時間

這位駭客大哥在博文中沒有留下任何身份資訊,也沒有透露用的反編譯工具,但是做好事不留名的他,把打好包的工具上傳到了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