Reputation: 13
I would like to pause execution time in c++ and this is the code I got:
while (_run)
{
//pause code
std::this_thread::sleep_for(std::chrono::nanoseconds(_interval_ns));
//doing stuff
_counter++;
(*_mainSrcTick)(GetDeltaTime(), GetName());
for (auto obj : _physicsList)
{
PyObject_CallMethod(obj, "PhysicsTick", "(d)", GetDeltaTime());
}
//used to mesure time
LastTick = std::chrono::high_resolution_clock::now();
}
Just in case here is my delta time function which gets how many ths of my interval have past since my last tick:
double difference = std::chrono::duration<double,std::nano>(std::chrono::high_resolution_clock::now() - LastTick).count();
double result = difference/_interval_ns ;
return result;
The problem I have is that by not pausing apparently my code can run in a couple of us and with pausing for a little time even it takes milli seconds. So forth I want a way to pause that doesn't disrupt my program so much.
Before you wonder I do know how to use "using namespace" and this project runs on x64 (though I wouldn't mind if it could also be run on x86), links python with c++ and is multi threaded, though on the python side only. So I presume I need a faster way to pause or at least time so it can pause with a while loop. I don't want ANY 3rd party dependencies. I use VS 2019.
The purpose is to make do stuff happen at a fixed frequency of every _interval_ns. GetDeltaTime is so I can give any inaccuracies to dostuff but it would be better if the frequency is accurate not the delta time. I am looking for micro second accuracy and nano would be nice.
Upvotes: 1
Views: 380
Reputation: 249153
When you ask your thread to sleep, it is unscheduled by the operating system, and rescheduling it takes some time. If you want to pause for a very small amount of time, use _mm_pause()
. You may want to do it a fixed number of times based on your own measurements of how long it takes on your system. Intel says it takes 140 cycles on Skylake (it took much less time on older CPUs): https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_pause&expand=5146
If the amount of time you want to sleep is small but you care about how much actual time has passed, you can check the time in a loop and call _mm_pause()
once per loop. About 70 ns for clock_gettime()
plus 40 ns for _mm_pause()
should give you a resolution somewhere around 120 ns on Skylake.
In either case, you will not be explicitly releasing the CPU core to be used by other processes, and the OS may unschedule your thread if there are other threads waiting to run on the same core. So you'll need to set your CPU affinity such that nothing else can run on the same core. For details see https://www.suse.com/support/kb/doc/?id=000017747
Upvotes: 1
Reputation: 782
If you do not want to pay for the thread context switch consider not switching thread context for example by using coroutines.Here Gor Nishanov claims that suspending and resuming a coroutine takes less than a nanosecond
Upvotes: 0