Странное «спящее» поведение между системами - PullRequest
7 голосов
/ 02 января 2012

У меня есть программа, которая использует Sleep Win32 API-вызов, чтобы заставить поток ждать определенное время.
Короче говоря, он имитирует камеру, отправляя предварительно загруженные изображения в память.Я использую Sleep для имитации частоты кадров - Sleep(1000 / fps)

Это прекрасно работает в моей системе разработки (Intel i5 (1st gen), Win7 64), но когда я запускаю ее на другой системе(Intel i7-2600 - SandyBridge), время ожидания совершенно разное и неточное.

Например, Sleep(16) спит около 32ms
Sleep(3), спит 16ms

Раньше я думал, что в окнах 15ms есть минимальное время сна, но я не получаю этого ограничения в моей системе разработки.

Любые идеи?

Кроме того,Есть ли лучший способ достичь частоты кадров моего симулятора?

Ответы [ 2 ]

7 голосов
/ 02 января 2012

Функция sleep гарантирует, что вы будете спать как минимум столько, сколько указано в звонке.Это заставляет поток приостанавливаться, позволяя переключаться на другие потоки (регулируемые приоритетами потоков) на досуге планировщика.Другими словами, спящий поток не гарантированно будет запущен сразу после истечения указанного времени , поэтому в общем случае следует избегать использования sleep для точной синхронизации.

Однако есть способы добиться более точного сна в Windows.Вы можете позвонить timeGetDevCaps, чтобы определить минимальное поддерживаемое разрешение таймера, а затем вызвать один раз в своем приложении timeBeginPeriod, чтобы установить минимальное разрешение таймера.Обязательно позвоните timeEndPeriod до выхода из приложения.

Для получения дополнительной информации см. функцию Sleep в MSDN .

1 голос
/ 02 января 2012

Вместо того, чтобы полагаться на неточное поведение сна или функции таймера для конкретной платформы (которые могут хорошо работать, я не знаю), вы можете структурировать это как игровой цикл.

Внутри цикла вы вызываете функцию, чтобы узнать текущее время. Вы выясняете, сколько времени прошло с тех пор, как вы нарисовали последний кадр, и решаете, когда визуализировать следующий кадр самостоятельно, в нужное время. Во время разработки вы должны измерить фактическое количество кадров в секунду и отобразить его.

При таком подходе ваш код становится кроссплатформенным и более точным. Кроме того, ваш цикл контролирует, а не структурирует ваш код как обратные вызовы таймера, которые вы также можете предпочесть.

Недостатком является то, что цикл «занятого ожидания» означает, что ваш процесс будет использовать ЦП все время без необходимости. Чтобы уменьшить это, вы можете снизить нагрузку на процессор в цикле, явно закачивая события пользовательского интерфейса некоторым образом или, возможно, используя более короткий сон :-)

Если вы хотите узнать больше об этом подходе, тогда начните поискать материалы по игровым циклам.

Вот несколько важных ссылок:

http://www.koonsolo.com/news/dewitters-gameloop/

http://gafferongames.com/game-physics/fix-your-timestep/

И обсуждение SO:

https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...