How to create timer intervals that are not a multiple of 1 millisecond?

# How to create timer intervals that are not a multiple of 1 millisecond?

• 28 กุมภาพันธ์ 2555 4:02

I've read that the physics engines of many PC based games use an interval rate that is not a multiple of 1 millisecond, for example, at a rate of 240hz (4.1666 milliseconds) or 360hz (2.7777 milliseconds) as opposed to a rate of 250hz (4 milliseconds) or 333hz (3 milliseconds). How is this done?

If this question would be better answered in another forum, please let me know which forum I should repost to (or can a moderator move the question and let me know where it got moved to).

• ย้ายโดย 8 มีนาคม 2555 2:59 (From:Visual C++ Language)
•

### ตอบทั้งหมด

• 28 กุมภาพันธ์ 2555 5:57

rcgldr wrote:
>
>I've read that the physics engines of many PC based games use an interval
>rate that is not a multiple of 1 millisecond, for example, at a rate of
>240hz (4.1666 milliseconds) or 360hz (2.7777 milliseconds) as opposed to
>a rate of 250hz (4 milliseconds) or 333hz (3 milliseconds). How is this
>done?

I'm not sure how you could tell.  Your LCD monitor only refreshes at 60 or
70 Hz.

However, Windows does not use the millisecond as a fundamental unit.  The
scheduler runs at a much slower rate (10ms or 16ms).  Most games run run
their main loops in a 100% CPU loop, so they can do whatever timing they
want.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc.
• ทำเครื่องหมายเป็นคำตอบโดย 8 มีนาคม 2555 3:02
•
• 28 กุมภาพันธ์ 2555 7:01

>> I've read that the physics engines of many PC based games use an interval rate that is not a multiple of 1 millisecond, for example, at a rate of  240hz (4.1666 milliseconds) or 360hz (2.7777 milliseconds) as opposed to a rate of 250hz (4 milliseconds) or 333hz (3 milliseconds). How is this done?

> I'm not sure how you could tell.  Your LCD monitor only refreshes at 60 or 70 Hz.

This is information reported by the game developers. There's no obvious external effect from the internal physics rate (which is independent of the monitor refresh rate) unless a higher rate solves some sort of physics problem in the game. In the case of few specific types of racing games, the physics engine rate can be adjusted (specified in hz).

> However, Windows does not use the millisecond as a fundamental unit.  The scheduler runs at a much slower rate (10ms or 16ms).  Most games run run their main loops in a 100% CPU loop, so they can do whatever timing they want.

The games I'm thinking of are multi-threaded, but the physics engine may be lower priority and running in a cpu loop, polling a high frequency timer to control it's rate.

A multimedia timer could be use to call a function or set an event that a thread pends on, with a resolution of 1ms (at least since Windows 95), but that wouldn't explain how rates like 240hz or 360hz are implemented.

• 1 มีนาคม 2555 6:03

I see some questions about timers in C++ general section, perhaps this thread could be moved there?

• 1 มีนาคม 2555 23:16

rcgldr,

This info has been getting harder to find in the last few versions of VS.  What you need to do is "NtSetTimerResolution" a win32 call in the NTDLL.DLL

You will have to look up the systax and add the required includes, but you can use this API to get to 1/2ms (2000 Hz).

-QuickC

• 2 มีนาคม 2555 13:31

Why not use hight precision timer with CreateWaitableTimer() , SetWaitableTimer() and WaitForSingleObject() ?

See an example below:

HANDLE InitialisationHORLOGE_InternePRECISE( char *ClockNAME)
{
HANDLE hTIMER_Interne;
hTIMER_Interne=CreateWaitableTimer( NULL, false, ClockNAME);
return hTIMER_Interne;

}

bool SpecialSleep( HANDLE hTIMER_Interne, int TimeToWaitInMicroSeconde)
{
LARGE_INTEGER Intervalle;
DWORD EtatATTENTE, TimeOUTms;

TimeOUTms=DureeAttenteMicroSeconde/1000;

SetWaitableTimer( hTIMER_Interne, &Intervalle/*x100ns*/, 0 ,NULL, NULL , 0);

EtatATTENTE = WaitForSingleObject(hTIMER_Interne, TimeOUTms);
if( EtatATTENTE == WAIT_TIMEOUT ) return false;

return true;
}

Delphine GARRO

• เสนอเป็นคำตอบโดย 2 มีนาคม 2555 16:48
• ทำเครื่องหมายเป็นคำตอบโดย 8 มีนาคม 2555 3:02
•
• 2 มีนาคม 2555 16:46

> CreateWaitableTimer() , SetWaitableTimer() and WaitForSingleObject()

Thanks for the info, I wasn't aware of these.

I will try them out to see what results I get. I've been using the multi-media timers, timeSetEvent(1, 0, ...) in a similar way (set an event that a thread pends on or use a callback function), but I've since determined that multi-media timers are 1024hz, but fake 1000hz, by using 3 double tick cycles every 125 cycles, on the 42nd, 84th, and 125th ticks (repeating that pattern), (125 ticks + 3 added cycles) (1000)/(1024) = 125 ms (getting back on exact 1ms boundary.

I'll try those functions to see if I get better (more precise) results.

• แก้ไขโดย 2 มีนาคม 2555 16:49
•
• 2 มีนาคม 2555 22:33

> CreateWaitableTimer() , SetWaitableTimer() and WaitForSingleObject()

I tried these functions using a repeating period of 1 on SetWaitableTimer(..., ..., 1, ...), but it ran at 64hz , 15.625 ms per tick by default. Using the multimedia function timeBeginPeriod(1) increased rate to 512hz, 1.953125 ms per tick, and appears not to add any cycles to fake running at 500hz, which at least provides a steady rate.

Can this thread be moved to visual C++ general, which is where the other timer related theads seem to be located?

• แก้ไขโดย 2 มีนาคม 2555 23:00
•