當前位置: 華文問答 > 遊戲

如何看待小米部份機型執行【王者榮耀】時兩個大核被鎖?

2017-11-11遊戲

發現大家都沒怎麽從技術的角度去解釋這件事情, 那麽我就從技術的角度來分析一下這個問題,讓小米和王者榮耀該背鍋的背鍋,該甩鍋的甩鍋.

作為一個技術男, 我們需要弄懂下面三個問題,給吃瓜群眾一個交代

  1. 第三方套用/遊戲有沒有能力做這件事?
  2. Rom 廠商是如何做到的?
  3. 為什麽要這麽做?
  4. 有什麽需要改進的?
  5. 為啥修改機型後就不鎖了?

結論先行,不喜歡看分析的吃瓜群眾可以直接看結論然後開噴:

  1. 第三方套用/遊戲在沒有 Root 的情況下,是沒法做這件事的,除非遊戲廠商和 Rom 廠商有合作.
  2. 關核行為是小米做的而不是王者榮耀做的.
  3. 為什麽要這麽做 : 為了溫控,為了能多玩幾把,為了不燙手,一切為了使用者,只是做了均衡和妥協,沒法讓所有人滿意而已.
  4. 有什麽需要改進的 : 不要只鎖核,不鎖頻,不限核. 關鍵 Log 還是不要輸出的好
  5. 修改機型後不鎖了是因為 MIUI 判斷不了你修改的機型, 所以對應的功能沒有開啟.

下面是分析:

1. 第三方套用/遊戲有沒有能力做這件事?

在一般情況下,像 cpu hotplug (動態開關 cpu 核心)這種事情,一般的第三方套用和遊戲是沒法去做這個的,因為涉及到要修改的程式碼或者節點,第三方套用一般都是沒有許可權的.

另外第三方套用/遊戲一般也不會針對某個機型或者某個 Rom 去做針對性的最佳化(當然 Oppo 和 Vivo 是個例外,畢竟花了不少錢),一來是成本太高,二來 Android 目前碎片化這麽嚴重,忙不過來也沒有必要.

高通那邊有一次培訓說是提供了一個 sdk ,讓套用可以在高通的機型上,設定自己的 cpu affinity,這應該是套用能獲得的最高的許可權了吧(不過有條件,最終還是取決於底層的判斷).

2. Rom 廠商是如何做到的?

Rom 廠商可以針對遊戲或者套用進行客製化,前提是你的套用有一定的體量,比如王者榮耀和微信,使用者基數大的足以讓所有的國產 Rom 廠商對其制定特定的策略,讓你在使用的時候更爽一些(當然如果沒客製好,就有可能出現體驗衰退)

前面結論說 Rom 廠商可以針對套用和遊戲客製策略,其中 cpu 的策略有如下幾種方法:

1.cpuset : 透過客製 cpuset ,可以限制某個行程或者某個執行緒,只執行在 cpu 的某個核心上.不過小米這個我看了下,並沒有進行客製,王者榮耀啟動後,靜靜地躺在預設的 top-app 裏面.

╰─$ adb shell ps | grep sgame u0_a152 16411 808 1597432 241496 0 0000000000 S com.tencent.tmgp.sgame ╰─$ adb shell cat /dev/cpuset/top-app/tasks | grep 16411 16411

而 top-app 的配置是預設的 0-7

╰─$ adb shell cat / dev / cpuset / top - app / cpus 0 - 7

也就是說沒有透過 cpuset 去限制王者榮耀跑在哪個核心上.

2.cpu affinity : 透過設定 affinity ,也可以讓某個行程跑在某個核心上,具體大家可以自己去 google 一下.

由於我手上的小米6沒有 root, 看不了對應行程的 affinity 配置,所以這個暫時可以放一下,過兩天我帳號 root 之後就知道答案了.

╰─$ adb shell taskset -a -p 16411 taskset: failed to get 16411's affinity: Permission denied

3.cpu hotplug : 其實就是動態開關核,這個第三方套用是做不了的,所以做的話只可能是 Rom 廠商做的.

4.cpu affinity + cpu hotplug : 可以理解成開關核 + cpu 繫結

透過上面四個方法,手機廠商可以對特定的套用做特定的 cpu 策略,比如王者榮耀.從目前的現象來看(套用啟動後,將 cpu6和 cpu7 這兩個大核關閉,只開兩個大核來跑王者榮耀),小米很大可能是用了第四種方法.不過從 Systrace 來看,似乎是沒用cpu affinity 將王者榮耀繫結在兩個大核上,所以王者榮耀跑起來的時候,其兩個比較重要的 unity 執行緒,既有可能跑在小核上,又有可能跑在大核上.

口說無憑,我們來從 trace 和 log 兩個方面來說明:

1. Systrace

從上面的 trace 來看, UnityMain 跑在小核上面(這是因為沒有玩,負載比較低)

上面的 trace 是玩的時候, UnityMain 的狀態,可以看到大部份都跑在大核上,但是有時候小核也會跑一部份,這會有什麽問題呢? 小核最高主頻低,像上面圖中,小核的頻率在300MHz, 那麽這一幀很有可能執行很久,導致掉幀.

2. Log

在開發的過程中,為了 debug, 我們會在程式碼裏加入很多的 log, 幫助我們分析問題,這裏我們也可以從 log 來入手

首先我們以王者榮耀為關鍵字搜尋 log

1. 王者榮耀啟動 11-05 10:52:03.422 1839 7960 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.tencent.tmgp.sgame/.SGameActivity bnds=[324,395][506,577] (has extras)} from uid 10021 on display 0 2. 進入遊戲模式 11-05 10:52:03.505 2429 2492 I octvm_power: power mode [game] start 1509850323 11-05 10:52:03.505 2429 2492 I octvm_power: Action: set_thermal_config(game) for [foreground_change] 11-05 10:52:03.506 2429 2492 I octvm_drv: cur_global_config:[0], target mode:[game] 3. 一大堆參數設定 11-05 10:52:03.508 799 987 I ThermalEngine: #algo_type monitor 11-05 10:52:03.508 799 988 I ThermalEngine: handle_thresh_sig: SS Id SGAME-SS-CLUSTER1-SP1, Read xo_therm 30000mC 11-05 10:52:03.508 799 987 I ThermalEngine: sampling 1000 11-05 10:52:03.508 799 987 I ThermalEngine: sensor tsens_tz_sensor16 11-05 10:52:03.508 799 987 I ThermalEngine: thresholds 5000 11-05 10:52:03.508 799 987 I ThermalEngine: thresholds_clr 10000 11-05 10:52:03.508 799 987 I ThermalEngine: actions vdd_restriction 11-05 10:52:03.508 799 987 I ThermalEngine: action_info 1 11-05 10:52:03.508 799 987 I ThermalEngine: descending 11-05 10:52:03.508 799 987 I ThermalEngine: [VDD_RSTR_MONITOR-TSENS15] 4. 關閉 cpu6 和 cpu7 ╰─$ adb logcat | grep "ACTION: Hotplugged OFF" 11-05 12:05:23.499 799 987 I ThermalEngine: ACTION: Hotplugged OFF CPU[7] 11-05 12:05:23.513 799 987 I ThermalEngine: ACTION: Hotplugged OFF CPU[6]

從上面的 log 就很容易知道了, 簡單分析就是:小米針對王者榮耀做了個模式,一旦進入這個模式,就load 事先配置好的一堆檔,比如溫控,各種閾值, cpu 的核數等 . 在這個例子裏面, 王者榮耀的核數配置的是0-5,所以他起來之後,需要把 cpu6 和 cpu7 這兩個 cpu 關掉,以防止他們瞎逼跑.

3. 手機廠商為啥要這麽做?

  1. 為了溫控 : 大家都知道王者榮耀開了高幀率,玩起來既費電,又燙手,觸發溫控後限頻限核和難受,所以需要在這之間找個平衡,既能流暢地玩,又能多玩幾局,又不觸發溫控.所以在夠用的情況下,只開兩個大核要比四個大核全開價效比更高.也更難觸發溫控,這就是小米6玩王者榮耀機身溫度比較低的一個原因.
  2. 為了省電: 兩個大核比四個大核省電,這個就不用多說了. 要上高地了你手機沒電了, 估計要罵娘了
  3. 夠用就好 : 王者榮耀是吃 cpu 的一個遊戲,而且兩個關鍵的就 UnityMain 執行緒, 一般情況下兩個大核就完全夠用了, 再開兩個大核,帶來的收益不是很高.但是帶來的耗電那就不好說了.(當然吃瓜群眾會有很大極限環境,後台掛著 qq 微信 迅雷 網易雲音樂,前台再玩王者榮耀,這個就考慮不到了,兩個大核絕逼吃力)

手機廠商和遊戲廠商都不會和使用者作對,這一點大家可以放心,所有的初衷都是讓使用者玩起來更爽一些而已,只不過在目前的硬體限制之下(cpu 能力/ 手機結構 / 電池大小 / 溫控 )做一個均衡而已.

想想魯迅那句名言.

4. 有什麽需要改進的?

這個真的不好說, 因為需要考慮的東西太多,使用者環境的復雜是沒法預料的,你不可能一套策略讓所有人滿意,所以只能做到讓大部份人滿意.

下面從技術的角度來說一下

  1. 不要只鎖核,不鎖頻,不限核 : 最好進遊戲之後限制一下兩個大核的最低頻率 + 限制王者榮耀不要跑到小核上.
  2. 高低幀率區分對待, 有的使用者使用高幀率,有的使用者習慣低幀率,在這兩種場景下可以使用不同的策略
  3. 關鍵 Log 還是不要輸出的好

最終的發展應該是每一個使用者都有一套策略,而且是即時更新的, 這個只能寄托於後續 AI 技術的發展和在手機 OS 上的套用了.

5. 為什麽修改機型後就不鎖核了?

關於這個問題,其實也不用等測試結果出來(帳號登入要等72個小時後才可以 root ),太久了.

為了說明這個,我們先達成下面兩個共識 :

  1. Framework 和 Feature 程式碼維護 : 一般情況下, 像 miui / flyme 等國產 Rom ,都會在 Framework 層做很多的修改, 而一般 Framework 層的程式碼, 一般只有一套,套用在所有的 小米機型上
  2. Kernel 程式碼維護 : Kernel 程式碼一般不會公庫,一般是一個機型一套程式碼(當然有可能同芯片的機型會共庫)

一般情況下, 像遊戲模式這種大的功能, 是需要 Framework 和 Kernel 同時配合的 , 工作量是很大的. 而且這種大功能, 一般還需要 Kernel 的支持, 有些老機型的 Kernel 版本過老, 是沒辦法做這個 Feature 的.

結論一 : miui9 適配了這麽多機型, 針對王者榮耀最佳化的這個功能, 只可能在部份機型上才有.老機型雖然上了 miui9 , 但是很多功能都是閹割版本的, 不是 miui 團隊不想做, 實在是有限制.

另外,我們說 Framework 層的程式碼一般是共庫的, 一套程式碼適配 20 幾款機型, 那麽內部是怎麽區分機型的呢 ? 在這個例子裏面就是 : 針對王者榮耀的這個遊戲模式, 到底哪款機型支持哪款機型不支持呢? 答案就在那幾個機型資訊. Framework 這邊會會獲取那幾個機型資訊, 來區分是否支持某個 Feature ,比如下面那幾個:

╰─$ adb shell getprop | grep product [ro.product.board]: [msm8998] [ro.product.brand]: [Xiaomi] [ro.product.device]: [sagit] [ro.product.manufacturer]: [Xiaomi] [ro.product.model]: [MI 6] [ro.product.name]: [sagit]

關於上面幾個大家是不是很眼熟? 沒錯,很多教程教你修改的一般就是這幾個值,改為之後如下:

ro.product.manufacturer=OPPO ro.product.model=OPPO R11 ro.product.brand=OPPO ro.product.name=R11 ro.product.device=R11

問題是: 你改完這幾個, 王者榮耀認為你是 R11 , MIUI 卻懵逼了 , 這型號我不認, 沒有對應的策略 , Pass !! Pass !!

結論二 : miui9 根據機型來開啟或者關閉某些功能 ,或者根據機型來判斷是否支持某些功能. 所以你修改相關的機型資訊後, MIUI 拿到這個機型資訊, 不知道這個是什麽機型, 所以對應的功能就關閉了.

6. Oppo 和王者榮耀

大家不要再黑 oppo 和 vivo 了,在使用者體驗這裏他們還是做了非常多的工作的,比如王者榮耀.

oppo 和王者榮耀的最佳化如下:

  1. 從 Unity 引擎裏面,把一部份任務抽離出來,分到其他執行緒去執行,減少 UnityMain 執行緒的負載,也就是我們所說的多執行緒版本.
  2. 獨家 SDK (可能不是很準,但如果我和王者榮耀要 sdk, 會想知道下面幾點)
    1. 告訴你啥時候遊戲開了
    2. 告訴你負載增加了(4-5人團或者10人團)
    3. 告訴你啥時候遊戲結束了
    4. 網路方面的最佳化

其他手機廠商為啥不做咧 ? 沒錢唄... 你猜 oppo 和王者榮耀合作花了多少錢?

不過後續這個多執行緒版本會對所有人開放, oppo 的獨占期,也是測試期啊, 風險與機遇並存.

7. 時效性

大家這這這種技術問題,時效性很重要, 為了防止後續 miui 或者王者榮耀進行修改策略之後某些不明真相的吃瓜群眾來怒懟,所以這裏記錄一下版本號和修改日期:

  1. miui 版本號: MIUI.9.7.11.2 開發版
  2. 王者榮耀版本
    1. app : v1.31.4.13
    2. res : 1.31.4.14
  3. 手機 : 小米6
  4. 本問題最後修改時間 : 2017-11-5