Основной цикл программы съедает много времени CPU впустую. Документация предлагает
virtual void irr::IrrlichtDevice::yield()
который "заставляет устройство временно прервать выполнение и дать выполнятся другим процессам", этот метод надо вызывать в основном цикле, как я понял. В моём случае этот вызов снижает загрузку CPU до ~20%. Для снижения нагрузки CPU я сделал так:
#define MAX_FPS 50 #define IDLE_TIME ((1.0 / MAX_FPS) * 1000.0) int main () { ... while (device->run()) // Основной цикл { u32 time = device->getTimer()->getTime(); driver->beginScene(...); ... driver->endScene(...); device->sleep(IDLE_TIME - (time - device->getTimer()->getTime())); } ... }
Загрузка снизилась до 1-3%. Есть ли ещё способы снижения нагрузки?
device->yeild
while(Device()->run())
if (Device()->isWindowActive())
{
// ...
if (Driver()->beginScene(true, true, BACK_COLOR))
{
Scene->drawAll();
Env()->drawAll();
Driver()->endScene();
};
}
else
{
Device()->yield();
};
Например так. Когда окно не активно, "выключаем". Это не всегда подходит, тем не менее мы можем вставить "Device()->yield(); " куда хотим
Вот с таким блоком исчезает лишняя нагрузка на процессор:
device->yield(); //----
smgr->drawAll();
env->drawAll();
device->yield(); //----
Загрузка падает иногда почти до нуля,
определяясь, в основном, сложностью физики ..
даже не используя многопоточность и сохраняя мультиплатформенность кода.
#define timestepFreq 85 //Константа ограничитель. Физика будет пересчитываться не чаще 85 Гц
.....
u32 time = 0;
while(device->run())
if (device->isWindowActive())
{
device->yield(); //----
// physic world speed
if( device->getTimer()->getTime() >= time )
{
time = device->getTimer()->getTime() +1000/timestepFreq;
p_world->update(); // обновление физики
}
driver->beginScene(true, true, video::SColor(0,200,200,200));
......
device->yield(); //----
smgr->drawAll();
env->drawAll();
device->yield(); //----
......
driver->endScene();
}
else device->yield();
device->drop();
return 0;
}
Попробовал снижать нагрузку на CPU вышеуказанными способами - и device->sleep(...) и device->yield(). FPS понижается, как и положено, но в диспетчере задач все равно - 100% загрузки. Сам код ничего не делает кроме вывода одной картинки 800х600. В чем еще может быть дело? Запарился уже совсем..
Все, проблема решена.
>>Все, проблема решена.
Как решил проблему? Интересно же.
Наверно так:
if(elapsed<MIN_ELAPSED) { Sleep( 1); }
Тема в архиве.