[情報] GTAO一個if語句循環19.8億次 駭客嘲諷R星已回收

看板C_Chat (希洽)作者 (天國直達車)時間5年前 (2021/03/07 21:58), 編輯推噓25(25022)
留言47則, 26人參與, 5年前最新討論串1/1
俠盜獵車手Online一個if循環19.8億次,而且7年沒人去修它,駭客順手解決這個問題了 https://www.techbang.com/posts/84848-whats-the-worst-code-youve-ever-seen https://reurl.cc/ynvVOM 一支菸的時間,俠盜獵車手Online終於打開了。 「7年了!GTA 5 Online載入還是這麼慢??」 Reddit、Steam、HackerNews上,無數玩家吐槽抱怨…… 進遊戲少則等5、6分鐘,多則20分鐘。 終於,一個駭客實在忍不了,用反組譯編輯器逐條查看運行情況,終於找到原因。 原來,R星(遊戲開發商RockStar)寫的程式碼太沒有效率,載入時,一個if語句竟然循 環了19.8億次…. 誰佔用大量時間? 載入GTA 5 Online到底有多慢? Reddit相關群組發起的調查中,超過80%的玩家,都要等3分鐘以上,有的甚至超過15分鐘 。 而且,從7年前Online上線到今天,這個情況絲毫沒有改善。 脾氣不好一點的,早就開始罵髒話…… 但奇怪的是,如果你選擇是故事模式(單機版),載入就會快很多,感覺甚至像兩個不同 的工作室開發的遊戲。 以這位駭客的例子,他自己的硬體規格如下: https://reurl.cc/0DdNkK CPU,是老而彌堅的AMD FX-8350,2012年上市,採用「推土機」架構,超頻潛力驚人。顯 示卡還是GTX 1070。 這樣今天看起來老舊的配置,打開單機版GTA 5需要1分10秒,而載入Online版則6分鐘起 。 駭客用了最簡單的Windows任務管理器,來判斷Online版GTA 5在啟動時,都使用了哪些電 腦資源。 https://reurl.cc/bzYpeo 在1分鐘的時間分界線上,之前是載入的是單機和Online版通用的基礎內容,之後是 Online版獨有的內容。 可以看到,Online版GTA 5,載入時調用大量CPU資源至少長達4分鐘之久。 而同時,記憶體、GPU、硬碟的使用情況幾乎沒有明顯變化。所以,問題有很大的機率是 出在程式碼上面。 R星程式碼寫太爛! 駭客在開扒R星程式碼之前,就說:我聞到一股爛程式碼的味道… 為了找出到底那一部分程式卡住了CPU,他使用了工具Luke Stackwalker,對CPU任務堆棧 進行採樣分析。 Luke Stackwalker對於閉源應用程式,可以轉存正在運行的進程堆棧,和當前指令指針的 位置,以一定時間間隔建立一個調用樹。 最後將數據整合,就可以得到程式運行統計數據。 從結果上看,一共有兩個函數「卡住」了CPU: https://reurl.cc/WEN9yL 於是他使用專業的程式碼拆解工具,把GTA 5來了一個「開膛破肚」。沿著調用棧往下走 ,發現問題出在一個sscanf函數上 https://reurl.cc/nnvgyD sscanf的功能是讀取格式化的字符串中的數據,而在GTA 5中,它正在讀取的是一個10M左 右,有63000多個條目的JSON檔案。 這個檔案到底是幹什麼用的?這位老兄推測,這可能是遊戲內購商店的相關內容。 https://reurl.cc/kVyAkn 在具體運行時,sscanf對於每個有效值,逐個讀取每一個字符,然後返回結果,之後指針 移向下一個值,循環往復……直到把10M文件全部掃一遍。 再看第二個問題,這是一個存儲命令,對像是item,具體是什麼不得而知。 但是保存前,有一個if語句,逐一比較item內項目的哈希值,檢查它們是否出現在某一列 表中。 按照他的計算,這一步if,要執行(63000^2+63000)/2 = 1984531500次! 沒錯,等待載入前的十多分鐘裡,GTA 5用你的CPU,執行了19.8億次if命令。 如此簡單粗暴的編程思路,讓這位老哥哭笑不得: 既然對像有唯一雜湊函式,那為什麼不用hash map??? hashmap根據hashCode值存儲數據,大多數情況下可以直接定位到它的值,因而具有很快 的存取速度,但遍歷順序不確定。) 至於為什麼這樣,有網友推測最開始,if的循環次數並沒有這麼多,而是隨著開發,條目 不斷增多,最後到了積重難返的地步。 而之前的程式碼結構,誰也不願意去動。 就這樣,19.8億次if,一遍遍在世界各地玩家cpu上上演..... 至於第一個問題,駭客採用hook大法,不一一讀取字符串,而是: hook strlen 「快取」字符串起始和當前長度。 如果在字符串範圍內函數在此被調用,返回快取的值。至於if語句問題,就更直接了—— 完全跳過重複檢查,利用hash map插入項目,因為這些值是唯一的。 最後的結果如下: https://reurl.cc/NXleDp 現在,GTA 5Online版載入時間,從原來的6分鐘,下降到現在的1分50秒!而且,用的還 是七八年前的硬體規格。 在此,應該手動@R星:你學廢了嗎? 這位駭客在文章中沒有留下任何身份訊息,也沒有透露用的反組譯工具,但是做好事不留 名的他,把打好包的工具上傳到了Github,玩家透過一行程式碼就能下載: git clone —rec ------------------------------------------- 其實我看不懂 我只是覺得嘲笑R星很有趣 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.82.245.230 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_Chat/M.1615125522.A.B95.html

03/07 22:00, 5年前 , 1F
恩恩跟我自己發現的結果很像
03/07 22:00, 1F

03/07 22:04, 5年前 , 2F
真駭客本色
03/07 22:04, 2F

03/07 22:05, 5年前 , 3F
聽起來一開始資料少時比對資料,官方方式也很快所以沒差
03/07 22:05, 3F

03/07 22:05, 5年前 , 4F
程式碼這種東西有時候硬修反而跑出更多莫名其妙的BUG,
03/07 22:05, 4F

03/07 22:05, 5年前 , 5F
於是只能將就著能跑就行
03/07 22:05, 5F

03/07 22:06, 5年前 , 6F
但資料一多後,官方的笨方式就會很慢
03/07 22:06, 6F

03/07 22:06, 5年前 , 7F
好奇R星這次還會大刀開鍘嗎?
03/07 22:06, 7F

03/07 22:07, 5年前 , 8F
但有時BUG這東西,你不知道改一個會不會又跑出另一個甚至
03/07 22:07, 8F

03/07 22:07, 5年前 , 9F
多個。尤其是這程式之前是其他人開發的
03/07 22:07, 9F

03/07 22:08, 5年前 , 10F
所以不嚴重的優先排序比較後面,或者根本不管他
03/07 22:08, 10F

03/07 22:08, 5年前 , 11F
上一篇有人說被封鎖了
03/07 22:08, 11F

03/07 22:08, 5年前 , 12F
而嚴不嚴重,有時也是很主觀的
03/07 22:08, 12F

03/07 22:10, 5年前 , 13F
上一篇那個是真的嗎 找了一下好像沒有其他案例?
03/07 22:10, 13F

03/07 22:10, 5年前 , 14F
BUG就跟史萊姆一樣 解完一個變兩個 兩個變四個
03/07 22:10, 14F

03/07 22:10, 5年前 , 15F
這個讀取問題已經可以量化到用時間來評估了,R星應該主動
03/07 22:10, 15F

03/07 22:11, 5年前 , 16F
修正這個問題,而且有人都幫你找好解了
03/07 22:11, 16F

03/07 22:12, 5年前 , 17F
看起來很像是儲存的時候用了O(n^2)的方法,改用O(n)的ha
03/07 22:12, 17F

03/07 22:12, 5年前 , 18F
sh map加速
03/07 22:12, 18F

03/07 22:16, 5年前 , 19F
看不懂但覺得好屌=.=
03/07 22:16, 19F

03/07 22:16, 5年前 , 20F
optimize ticket優先度很低 沒人催的話通常會一直延
03/07 22:16, 20F

03/07 22:18, 5年前 , 21F
我看過一張ticket放在那邊兩年沒人做
03/07 22:18, 21F

03/07 22:19, 5年前 , 22F
儲存前會檢查一次是否重複儲存
03/07 22:19, 22F

03/07 22:20, 5年前 , 23F
但你都有map了....
03/07 22:20, 23F

03/07 22:38, 5年前 , 24F
我完全能理解 接受以前的人留下來的程式碼後完全不想動
03/07 22:38, 24F

03/07 22:39, 5年前 , 25F
反正跑得出來就好 效率什麼的要去修有時還不如自己重寫
03/07 22:39, 25F

03/07 22:42, 5年前 , 26F
同意樓上講的,接手改別人寫的程式碼有時候真的很頭痛
03/07 22:42, 26F

03/07 22:45, 5年前 , 27F
程式架構的設計邏輯都不是自己的,真的會怕哪邊想法沒對到
03/07 22:45, 27F

03/07 22:45, 5年前 , 28F
不過loading 20分鐘真的是發optimize不是issue嗎XDD
03/07 22:45, 28F

03/07 22:46, 5年前 , 29F
然後不改還好,一改就改出大問題......
03/07 22:46, 29F

03/07 22:47, 5年前 , 30F
不改還不是一堆人玩,改了要是出bug誰負責。當事情牽
03/07 22:47, 30F

03/07 22:47, 5年前 , 31F
涉到技術以外的層面就不是這麼單純的問題了
03/07 22:47, 31F

03/07 22:52, 5年前 , 32F
有人催ticket topic就會變成issue了啊 沒有就放給他爛
03/07 22:52, 32F

03/07 22:53, 5年前 , 33F
不然通常是先弄新feature 反正跑的動
03/07 22:53, 33F

03/07 22:54, 5年前 , 34F
逐一比對hash誰寫的 這種大學就要被當了吧
03/07 22:54, 34F

03/07 22:55, 5年前 , 35F
弄hash竟然不懂hashmap
03/07 22:55, 35F

03/07 23:11, 5年前 , 36F
真的有夠久 我都等10分鐘左右 開連線後就先去看影片了
03/07 23:11, 36F

03/07 23:18, 5年前 , 37F
相比rdr2線上載入就很快
03/07 23:18, 37F

03/08 00:27, 5年前 , 38F
程式設計裡有句老話,只要能動,就不要去改它
03/08 00:27, 38F

03/08 00:46, 5年前 , 39F
真駭客就是要自己修程式 XD
03/08 00:46, 39F

03/08 04:29, 5年前 , 40F
能work就不要隨便改他,程式設計必學的
03/08 04:29, 40F

03/08 04:29, 5年前 , 41F
當debug的人跟當初開發的不是同一個人的時候
03/08 04:29, 41F

03/08 05:05, 5年前 , 42F
團體寫code就是這樣 你不會想動能跑的東西
03/08 05:05, 42F

03/08 07:02, 5年前 , 43F

03/08 12:55, 5年前 , 44F
感覺就是寫這段code的人離職,然後就沒人想去改他了,新
03/08 12:55, 44F

03/08 12:55, 5年前 , 45F
功能就直接依樣畫葫蘆加上去,反正能work就好,比改他衍
03/08 12:55, 45F

03/08 12:55, 5年前 , 46F
生更多問題好
03/08 12:55, 46F

03/08 13:55, 5年前 , 47F
在忙著開發6啦 川普都下台了 當然在忙6囉
03/08 13:55, 47F
文章代碼(AID): #1WHDmIkL (C_Chat)
文章代碼(AID): #1WHDmIkL (C_Chat)