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

    Pregunta

  • 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).

    • Cambiado Helen Zhao jueves, 08 de marzo de 2012 2:59 (From:Visual C++ Language)
    martes, 28 de febrero de 2012 4:02

Respuestas

  • 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;

    Intervalle.QuadPart= (-10)*(DureeAttenteMicroSeconde);
    SetWaitableTimer( hTIMER_Interne, &Intervalle/*x100ns*/, 0 ,NULL, NULL , 0);

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


    return true;
    }


    Delphine GARRO

    • Propuesto como respuesta GARRO Delphine viernes, 02 de marzo de 2012 16:48
    • Marcado como respuesta Helen Zhao jueves, 08 de marzo de 2012 3:02
    viernes, 02 de marzo de 2012 13:31
  • 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.
    • Marcado como respuesta Helen Zhao jueves, 08 de marzo de 2012 3:02
    martes, 28 de febrero de 2012 5:57

Todas las respuestas

  • 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.
    • Marcado como respuesta Helen Zhao jueves, 08 de marzo de 2012 3:02
    martes, 28 de febrero de 2012 5:57
  • >> 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.

    martes, 28 de febrero de 2012 7:01
  • I see some questions about timers in C++ general section, perhaps this thread could be moved there?

    jueves, 01 de marzo de 2012 6:03
  • 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

    jueves, 01 de marzo de 2012 23:16
  • 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;

    Intervalle.QuadPart= (-10)*(DureeAttenteMicroSeconde);
    SetWaitableTimer( hTIMER_Interne, &Intervalle/*x100ns*/, 0 ,NULL, NULL , 0);

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


    return true;
    }


    Delphine GARRO

    • Propuesto como respuesta GARRO Delphine viernes, 02 de marzo de 2012 16:48
    • Marcado como respuesta Helen Zhao jueves, 08 de marzo de 2012 3:02
    viernes, 02 de marzo de 2012 13:31
  • > 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.

    • Editado rcgldr viernes, 02 de marzo de 2012 16:49
    viernes, 02 de marzo de 2012 16:46
  • > 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?



    • Editado rcgldr viernes, 02 de marzo de 2012 23:00
    viernes, 02 de marzo de 2012 22:33