[英]How do I use less CPU with loops?
我有一個看起來像這樣的循環:
while (elapsedTime < refreshRate)
{
timer.stopTimer();
elapsedTime=timer.getElapsedTime();
}
我在別處讀過類似的東西(
C Main Loop沒有100%cpu ),但是這個循環正在運行一個必須准確的高分辨率計時器。
那么我怎么能在保持高分辨率的同時不占用100%的CPU呢?
你不應該忙 - 等一下,而是讓操作系統告訴你什么時候過去了。
http://msdn.microsoft.com/en-us/library/ms712704(VS.85).aspx
高分辨率計時器(高於10毫秒)
當你說你的計時器必須“准確”時,你實際需要多准確? 如果您只需要精確到最接近的毫秒,那么您可以在循環內添加半毫秒的睡眠。 您還可以根據您剩余的睡眠時間添加動態變化的睡眠聲明。 想想(偽代碼):
int time_left = refreshRate - elapsedTime;
while (time_left > 0) {
if (time_left > threshhold)
sleep_for_interval(time_left / 2);
update_timestamp(elapsedTime);
time_left = refreshRate - elapsedTime;
}
使用該算法,如果代碼檢測到您還有一段時間等待,則代碼將短暫停留。 您可能希望運行一些測試以找到threshhold
的最佳值,以平衡CPU使用率節省的過沖風險(由於您的應用程序在睡眠時丟失CPU並且沒有及時獲得CPU時間)。
高分辨率定時的另一種方法是使用觸發周期性中斷的硬件定時器。 你的中斷處理程序會向某個線程發送一個信號,它需要喚醒它並做一些事情,之后它會重新進入休眠狀態並等待下一個信號進入。
實時操作系統有辦法在操作系統中內置這類內容。 如果您正在進行Windows編程並且需要非常精確的計時,請注意,像Windows這樣的通用操作系統處理得非常好。
查看操作系統提供的一些計時器,如POSIX usleep
。
另一方面,如果你需要超精度,你的代碼也不會工作,因為操作系統會耗盡它的進程時間量並跳轉到內核空間來完成一些系統任務,從而打破這個循環。 為此,您需要一些特殊的操作系統,其中包含可中斷的內核和工具; 尋找RTOS關鍵字。
通常,您以某種方式屈服於操作系統。 這允許操作系統從您的程序中休息並執行其他操作。
顯然這取決於操作系統,但是:
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
void yield(void)
{
#ifdef _WIN32
Sleep(0);
#else
usleep(1);
#endif
}
在停止計時器之前插入對yield的調用。 操作系統將報告您的程序使用時間更少。
當然,請記住,這會使您的計時器“不太准確”,因為它可能不會盡可能頻繁地更新。 但你真的不應該依賴極端准確性,這太難了。 近似沒問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.