怎樣知道FC,MD,SFC,老式街機基板等老遊戲機在運行時,CPU和內存的佔用率?

用戶在使用計算機的時候,可以用任務管理器查看當前CPU和內存的佔用率。

老式遊戲機,如FC,MD,SFC,老式街機基板,雖然性能遠沒有現代計算機給力,但它們也是計算機設備,在遊戲運行的時候,應該也能測出它們的CPU和內存佔用率的。

前幾年我在百度貼吧問過網友,有人說,遊戲機不像X86計算機那樣,能夠同時運行多個任務,遊戲進程運行時,CPU等已經無法運行監測它自身運轉的程序了。

還有網友說,需要另外附加專門的晶元,對遊戲機運行時的CPU,內存等部件的負載進行監控。

照理說,遊戲機在運轉某個特定的遊戲的時候,遊戲廠商必須知道它是否會超出遊戲主機機能的極限,超出極限會發生卡慢,掉幀,甚至遊戲無法正常運行等現象。如FC上的《魂斗羅力量》,可以視作一個超出FC主機機能極限而導致幀數嚴重不足的反面案例。

廠商的開發機,或其他開發遊戲的輔助計算機中,是否有模擬或監測遊戲運轉時,正常主機的CPU,內存等的佔用率的相關軟硬體機制?如果有,它怎樣實現?

難道這些遊戲廠商生產遊戲時僅憑經驗公式推算,以及試玩流暢度,不考慮遊戲佔用主機硬體資源的情況?這一塊是怎樣做的呢?


CPU的佔用率,簡單來說,不需要知道

8bit時代,無論是6502還是Z80,指令就那麼多,很容易計運算元程序整體的Cycle,邏輯處理在幀渲染中處理,渲染(也就是設定VDP寄存器)在VBlank裡面進行,NTSC環境下這些數字都是定死的。

那個時代,其中一些數字,比如一個水平刷新63.5微秒,一個垂直刷新16683微秒那都是要牢牢記在每一個程序員心中……

用FC舉例:

一個HBlank有24個Cycle,考慮到RTI指令需要用掉6個,實際可用18個,你可以用超過這個數字的Cycle,畢竟中斷這個東西一旦跳進了中斷Handler,什麼時候出來你說了算,但是如果你沒能在左側第一個像素開始渲染前設定好寄存器,畫面左側必然會出現一些奇怪的扭曲之類的

一個VBlank就是2507個Cycle,照樣,減掉6個Cycle的RTI,2501

如果你不用光柵特效就可以無視HBlank,整體邏輯在29856-2507=27349個Cycle之內完成就好

如果用,HBlank中斷Handler寫好了之後算一下需要的Cycle,乘上240,減去它就是留給遊戲邏輯可用的Cycle數,比如我用滿24個,確保第25Cycle一定會RTI結束,那留給遊戲邏輯就有21589個Cycle

什麼?你的遊戲太複雜?兩萬七千個Cycle之內實在完不成?

那就按30fps做唄,又不是沒有這樣的遊戲

FC上有57175個Cycle(29856+27349-大概30Cycle足夠判斷奇偶幀了)足夠你實現在時代限制下的基本所有想法了……

也有一些程序員腦洞清奇,比如岩田聰,F1 RACE裡面奇數幀處理一部分邏輯,偶數幀處理另一部分邏輯……

紅白機64合1大回顧(30):F1 Race 大賽車 - 長鼻君的懷古櫥 - 知乎專欄

那個年代開發遊戲這些都要算的,不過那個時代也沒有緩存,每一個指令,每一個內存訪問需要的Cycle數完全固定,並不會有任何浮動,所以這些計算還相對比較容易

16bit時代,MD時鐘周期有7.67MHz,街機用上68k更是12MHz起跳,基本上不需要算時鐘周期,CPU機能實在太充裕了,一部分MD遊戲和68k的街機遊戲甚至充裕到CPU軟體計算圖像旋轉,暫存到RAM里,然後用VDP渲染……

唯一需要算這個的是SFC,它時鐘周期只有3.58MHz,FC的兩倍,能用的Cycle是上面的數字乘2……當然作為16bitCPU,完成同樣的工作所需要的Cycle數降低了,而且得力於強力的VDP,旋轉縮放等等等等一應俱全,除了少數特效之外沒有用光柵特效的需求了,但是整體上依然是機能有限……

內存佔用率是需要知道的

但是那個年代並沒有動態分配內存的需求,所有的變數用全局變數的思考方法去寫程序就好

比如我做一個射擊遊戲,我一定會定一個上限,我的遊戲同屏彈數不會超過100發,不會同時超過50個敵人之類的,然後在內存里依照這個分配好就可以了

唯一一個需要考慮的變數是棧,畢竟棧裡面放著子程序的返回地址,在FC上如果子程序調用層數多了棧可能不夠用,區區2K內存分配完了留給棧的可能只有數百位元組,當然後期出現了擴展RAM的Mapper,自己動手豐衣足食嘛

等到16bit時代了,SFC有128K內存,MD有64K內存,怎麼說都夠了

不夠?上Mapper啊!

至於你說的那個魂斗羅力量……那是程序寫的垃圾的代表作品,完全不是FC的機能極限。君不見烈火92同屏幾十個活動快都不帶拖慢的,而且還有縱橫雙軸光柵背景特效……


其他的平台不熟,我這裡就說下FC吧。

首先的問題是:怎麼定義CPU使用率呢?在帶有操作系統的計算機環境下我們一般把某個進程的CPU使用率定義為一段時間內進程運行所消耗的CPU時間的佔比。

然而FC遊戲運行既沒有操作系統可以負責託管空閑CPU時間片,CPU也不支持睡眠功能,那如果遊戲1個tick的音畫渲染和邏輯處理完了還沒到1幀時間怎麼辦呢?當然是不停地執行無條件跳轉耗時間直到下一幀的中斷到來(有的遊戲是純粹耗時間,有些遊戲會拿這段時間做累加器用來當偽隨機數發生器),所以如果以通常的CPU使用率來定義的話那FC遊戲的CPU使用率就肯定是100%了。

雖然CPU是被100%佔用,但還是可以分「有效CPU使用」和「無效CPU使用」。運行遊戲主邏輯的代碼都是屬於有效使用,而一個tick跑完後拖時間的死循環就可以認為是無效使用。我們可以將有效CPU使用佔比視為FC遊戲的CPU的使用率。

那麼如何測定某一幀時間內CPU的使用率呢?如果在開發的時候一個簡單的方法就是把tick跑完之後拖時間的代碼改成一個累加器,使得值的增長速度和指令消耗的時鐘數同步,這樣通過這個計數就可以得知每幀的無效時鐘周期數,就能知道CPU使用率了。

不過這裡我打算利用virtuanes模擬器帶上點簡單的hack來估計下現有遊戲的CPU使用率,就以美版「魂斗羅」為例好了。

我的做法是,把無效CPU使用的代碼替換成可以提示當前PPU渲染畫面已經渲染到了哪一行了的代碼。其實這個實現還比較簡單,PPU寄存器0x2001的bit 0是控制當前渲染是彩色渲染還是黑白渲染,所以只要把tick完了最後那個替換成設置黑白渲染模式的代碼就行。由於PPU渲染畫面是從上到下逐行渲染的,只要看下畫面上從哪行開始往下的畫面都成了黑白色就知道1 tick跑完之後PPU工作到哪了。

那和CPU是什麼關係呢?這個就要知道PPU的工作時序了。

以NTSC制式為例,詳細的時序可以參見

http://wiki.nesdev.com/w/images/d/d1/Ntsc_timing.png

這裡就粗略的描述下好了:VBlank NMI中斷信號到來(遊戲主邏輯開始新tick運行),PPU先是處於「睡眠」狀態,持續時間大約佔一幀的8%,然後剩下約92%時間就是在逐行渲染了。這裡為了簡便就不考慮pre render和post render line了。

那麼就可知,如果按前述測量方法,某幀的畫面全部變成灰色,那麼可以認為該幀CPU使用率小於8%。如果畫面的彩色部分佔比為x%,那麼可以認為該幀的CPU使用率大約是(8 + x * 0.92)%。

利用virtuanes debug版運行美版魂斗羅,利用debug找到tick後拖時間的代碼(看起來像是個隨機數發生器)

然後用普通版本virtuanes打開遊戲(debug版CPU頻率被人為調快了),按P暫停模擬器,打開內存查看器,找到0xC057處直接修改RAM,把A5 1A 65 34 85 34改成A9 1F 8D 01 20 EA,修改後的二進位碼對應的彙編是:

C057: A9 1F LDA $#1F
C059: EA NOP
C05C: 8D 01 20 STA $2001
C05D: 4C 57 C0 JMP $C057

看下效果吧!(需要在設置里打開240線渲染)

遊戲開始時大概就在這個位置(會有上下波動),彩色部分佔25%,可推算出此幀期間CPU使用率為大約31%。

再往後玩,發現第一關過橋到第一個炮台這裡CPU消耗很大,已經是90%左右了。

利用單幀步進的方式看下S槍開槍時候的CPU處理消耗吧:

開槍的那一幀CPU消耗高了25%左右,也就是說初始化S彈的5顆子彈要花費7000多個CPU周期


應該是沒有內存佔用率的概念的。

FC和GB等基本上不存在操作系統的層,內存管理由遊戲直接進行,一般也就是進行靜態分配,哪段內存幹啥在遊戲設計的時候就進行好分配了,分配到的不管你有沒有進行讀寫都要在那裡占著,沒分配到的除去程序出錯否則自開機到關機都不會用到。

至於CPU佔用率,這個倒是有可量化的東西,具體到GB大抵上就是單位時間內CPU處於非HALT或STOP狀態下時間的佔比。

CPU要與外圍硬體進行交互,然而外圍硬體的速度相比CPU速度往往較慢,而且不是任何時間都能訪問外圍硬體。有一種傳統的辦法是CPU循環檢測外圍硬體狀態,只要合適了就進行訪問,這樣的方式效率當然低下而且耗能,因此一般採用的是中斷處理,即你要與外圍硬體交互時,先進行交互前的準備,之後執行HALT,CPU不再執行命令,而是等到硬體發出信號後CPU自動跳轉到某個中斷程序進行處理,所以HALT時CPU就相當於處於空閑狀態。

不過這些都是基於不完善的模擬器使用經驗做出的看法,我並沒有見過這類遊戲的實際開發,更沒見過開發機。

這是BGB模擬器中的調試工具,右邊中部那個豎條就是CPU佔用率。

就實際體驗而言,如果是相對合理編寫的程序(題外話:GameFreak糞程序!),就算這個條子達到100%,除了長時間這樣你會覺得耗電以外,並不會有其他的感覺,因為中斷程序的執行能夠讓聲音畫面等在合適時間持續進行輸出,讓你感覺不到什麼區別。

魂斗羅力量個人覺得並不是什麼機能問題,而是程序質量的問題,大概是將中斷關閉去處理某些數據(很有可能是類似於輪詢硬體狀態的東西),然而關閉的時間過長導致聲畫變得拖慢詭異。另外 理論上單核CPU,不管你是不是X86都不能同時執行多任務吧,也都是靠中斷來完成「多任務」,FC和GB能同時給你顯示畫面、放音樂、處理遊戲其他數據,也是靠中斷來進行的,只不過FC和GB等的中斷沒有X86那麼複雜罷了。


10.15.補

突然想到手頭有盤FC卡帶CPU負荷顯示的。

可能知道的人不多,今年年初發行的,純音樂播放軟體。具體各位百度吧。

由於改卡帶ROM沒有公開dump,以下照片為實機。

遊戲標題

Option里,可以看到select可以顯示CPU負荷

正常播放界面

打開CPU符合展示後,畫面出現類似半透明效果的動態來表示CPU負荷

==以下原回答

瀉藥....

聲明:本人不是計算機軟硬體行業從業者。為避免糾紛,不會做深入講解。

結論:遊戲ROM的工程版本中基本上都會有相關的DEBUG菜單,主要是用來做一些功能調試遊戲測試的,其中不少DEBUG菜單中包含顯示了硬體使用率,RAM,ROM,CPU,PPU使用率,幀率等。一些基本功能不需要額外附加的硬體。這些代碼功能在正式發售的遊戲里會被剔除或者做簡單的屏蔽。

FC,SFC,MD,街機等正式零售的ROM版本中仍然包含了大量的DEBUG功能。比如街機的很多調試功能可以通過框體基板上的DIPS開關來開啟。家用機遊戲的部分ROM DEBUG菜單可以使用硬體金手指開啟。模擬器上也可以。

當然,顯示方式並不如windows任務管理器那樣直觀....基本都是16進位數值表示的....

例子不勝枚舉....

MD Disney"s Aladdin

零售版ROM包含DEBUG菜單

RAM和ROM使用率顯示在此。

SFC Star Fox 2工程版

此遊戲因故取消了開發和發售,網上可以找到工程版。工程版最明顯的特徵是左上角實時顯示遊戲幀率。此遊戲可以用正版Star Fox一代卡帶替換燒錄ROM在實機上使用。

FC Toxic Crusaders

零售版ROM隱藏DEBUG菜單

CHR內存和活動塊相關的地址...========================

待更。無限期留坑。


老遊戲機都是數指令周期的,內存也是全部靜態分配。

Atari 2600 內存只有 0.1K,每個位元組甚至都要考慮復用


這些遊戲機都有相應的開發機,我想開發機上應該能監視到各種使用率的


傳統的主機算佔用率有什麼意義?同時只能執行一個程序,甚至連作業系統也沒有,也不存在後台的概念,幾乎一切硬體資源都是由遊戲程式以真實模式獨佔的。


推薦閱讀:

知乎上有多少知友從事基於cocos2dx或是其他cocos2d遊戲引擎的遊戲開發的?
為什麼世嘉土星做不到真3D?
怎樣製作一款以打雪仗為主題的遊戲?
EVE遊戲程序的技術在哪個層面?
怎樣快速製作一個圖形化的邏輯編輯器?

TAG:家用主機遊戲 | 遊戲開發 | 遊戲機 | 電腦硬體 | 懷舊經典遊戲 |