#What is the better way to tackle this precise sleep timing

26 messages · Page 1 of 1 (latest)

zinc mulch
#

Spinlocking does not feel good and std::this_thread::sleep_for() is too inaccurate

void spin_for_target_fps()
{
    static auto curr_time = std::chrono::high_resolution_clock::now();
    static auto new_time = std::chrono::high_resolution_clock::now();

    u64 target_dt_ns = 1'000'000'000 / win.get_spec().target_fps;

    u64 curr_dt_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(new_time - curr_time).count();

    {
        KAWA_PROFILE("target fps spinning");

        while (curr_dt_ns < target_dt_ns)
        {
            new_time = std::chrono::high_resolution_clock::now();
            curr_dt_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(new_time - curr_time).count();
        }
    }

    curr_time = new_time;
    new_time = std::chrono::high_resolution_clock::now();
}
rancid graniteBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

hidden depot
#

If you yield your cpu time, you are only guaranteed to get back to the cpu at least after your wait time

bleak thistle
#

You could sleep, get woken 1ms early and spin for the rest of the time for accuracy.

lethal fulcrum
#

or you could tick the timers on the gameloop and check if they should fire

#

but how is it too inaccurate, what kind of fps you need

#

a simple sleep(0) should work

hidden depot
lethal fulcrum
#

on windows tho

hidden depot
#

It was not accurate

#

Also the length of the sleep doesn't really correlate to the accuracy above a certain small threshold

#

It is practically random, depending on other processes

lethal fulcrum
#

I lost the actual code and only have a disassembly of what I did but it was a timer incrementing on game loop and calling sleep(0) if last update was < 1/fps ago

#

and it was fully accurate to all common fps values, 30/60/120/144/165/240

lethal fulcrum
lone totem
#

Does it have to be a portable solution? If not, what OS support is needed? I had a similar problem to solve on Windows and I’m trying to find the solution again, but it was definitely platform specific.

#

Okay so I’m not on a Windows rn, but IIRC the solution was to call https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod
and
https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timeendperiod
respectively, and then std::this_thread::sleep_for was accurate enough for my use case. Can’t help with other platforms, but if setting the clock resolution is possible, It might be a good idea to try to.

The timeBeginPeriod function requests a minimum resolution for periodic timers.

The timeEndPeriod function clears a previously set minimum timer resolution.

glass jewel
#

whats your target platform? for windows the function i see being used by libstdc++ and libc++ was Sleep or SleepEx which are not precise since the thread can be rescheduled and delay the startup by the system’s clock interval

glass jewel
lone totem
#

I mean, games do this anyways afaik

glass jewel
zinc mulch
#

in my extensive reserch a came to a conclusion that spinlocking + sleep_for combination or even straight spinlock is good enough

#

!solved