改良cocos2dx Win32下的內存佔用

猜想它有多是在主循環裏使用了 Sleep(0), 一搜,果真定位到具體代碼,它位於 cocos2dx\platform\win32\CCApplication.cpp,大體長像以下:函數

1 while( 1 ) {
2 if( 有消息 ) {
3 if( 時間到 ) 更新計時, call 主循環函數;
4 else Sleep(0);
5 }
6 // 其餘跳出循環判斷代碼
7 }

 

也就是說,該循環除了執行 mainLoop 之外,花了大量時間在 檢查消息和 Sleep(0) 上面。oop

 

而且,我還發現一個奇怪的現象(暫時還不清楚是爲何),即:測試

HelloCPP 項目的 AppDelegate.cpp 文件中有一行代碼:this

// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);

  

 

上面的 60 ,若是改大,不起任何做用,幀速始終是 60 不會變。但若是改到小於60,是能夠起做用的。.net

 

因而,解決 CPU 佔用的思路,始於 「是否能夠下降循環精度」 的念頭。code

已知正常狀況下,執行 Sleep(1) ,會睡大概 1/50 秒,這個時間並不精確也不許確,看上去沒法知足 60 fps 這個流暢度需求。不過,若是遊戲運行幀速不須要這麼高,好比 30 fps ?? 則該方案大爲可行。orm

 

經實際測試,將 Sleep(0) 改爲 Sleep(1), 再將上面代碼中的 60 改爲 25, 效果很是顯著。但另外一個問題來了:若是每遊戲循環作的事有點多,時間有點長,那麼遊戲將被拖慢。遊戲

 

原engine中,同步時間的代碼以下:get

 

QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart) {
nLast.QuadPart = nNow.QuadPart;

  

由於每次在 nLast 中記錄 nNow 時間,並用時間差與設定間隔做比較,時間差每每會比設定間隔要大,若是是在不精確的 Sleep(1) 以及每循環負擔比較大的狀況下,將致使每幀實際所花的時間,會超出設定間隔很多,從而拖慢遊戲速度(若是遊戲按幀步進計時的話)。同步

爲解決這個問題,我用的是時間對齊的方式。其實就是改了一下更新 nLast 的表達式:

 

nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart %m_nAnimationInterval.QuadPart);

  

這樣每幀的總消耗時間就至關的恆定了。

 

上面的問題解決並不算太完美。如何保持 60 fps 也能 cpu 0% 佔用呢? 我考慮的方案是修改 Sleep(1) 的精度。

找了一下資料,發現 Winmm.lib 庫中有   timeBeginPeriod(1);    timeEndPeriod(1);    函數能夠用於該目的,令 Sleep(1) 的精度提高到1毫秒級別,遂動手改之:

1. 添加 Winmm.lib 庫的引用。我在這裏採起了在 CCApplication.cpp 頭部添加  #pragma   comment(lib, "Winmm.lib")  語句的方式。

2. 在 while(1) 代碼段的先後,分別放上 timeBeginPeriod(1);    timeEndPeriod(1);  語句

這樣就算完工了。

 

經測試,幀速設定在 59 fps 之內, cpu 均可以實現 0 佔用 (i7 2600k)。設成 60 的話, cpu 佔用會週期性的古怪浮動,暫時不明就裏中。而設成 60+, cpu 將 100%。

不過該問題就算暫時告一段落,先將程序限定到 50 fps 好了,流暢,無問題,感受上也方便計算...

相關文章
相關標籤/搜索