Hi,
I’m trying to locate the source of a regular jitter when calling Windows
::Sleep(2) within a loop. I realise that Sleep() by definition is
unreliable – and Windows is not realtime –, but because my output
results are so regular, someone might immediately know the cause?
Code:
-----
Essentially, this just calls a loop within which QueryPerformanceCounter()
and Sleep(2) are called.
// grab timings
unsigned _int64 startTime;
unsigned _int64 timerRate;
unsigned _int64 sampleTime;
QueryPerformanceCounter((LARGE_INTEGER *) &startTime);
QueryPerformanceFrequency((LARGE_INTEGER *) &timerRate);
int counter = 0;
int timeUS[10000];
while( ++counter < 10000 )
{
QueryPerformanceCounter((LARGE_INTEGER *) &sampleTime);
int time = (sampleTime - startTime) * 1000000 / timerRate;
timeUS[counter] = time;
Sleep( 2 );
}
// print output
const std::string filename = "C:\\out.csv";
FILE * fo = fopen( filename.c_str(), "w" );
if( fo )
{
fprintf( fo, "Counter%cTime%cDelta\n", ',', ',' );
int timeUSStart = timeUS[0];
for( int i = 0; i < 9999; ++i )
{
fprintf( fo, "%d%c", i, ',' );
fprintf( fo, "%d%c", timeUS[i] - timeUSStart, ',' );
fprintf( fo, "%d%c", timeUS[i+1] - timeUS[i], ',' );
fprintf( fo, "\n" );
}
fclose( fo );
}
Results:
--------
Cannot attach plots, so please bear with me... I have the CSV file / XL
plots if anyone wants it...
As expected, most of the output shows a delta time of 2000 us, i.e. 2 ms.
However, there is a big jitter every 499 samples - i.e. 1 second -, bang on
the dot. At this sample point the output jumps to 4300 us, i.e. an
additional delay of 2.3 ms. The following sample drops to 1700 us, i.e.
there is a small speedup. It then returns to 2000 us delays.
I accept that Sleep() is inaccurate. But whatever my code loop is doing,
at least it’s consistent and precise.
Questions
---------
So, firstly, do you think this delay that occurs every 499 samples, i.e. 1
second, is due to some regular external event under Windows, or could it be
due to my code (e.g. the Sleep() command itself)?
If it is due to an external event, are there any Windows tools that
diagnose and track down the cause?
If it is due to the Sleep() call itself, is this a deterministic jitter
that we can filter out, are there other variants of Sleep() I can use, or
any other ideas? Or is the answer simply: ‘Yeah, non-realtime OS: just
accept it and move on’?!?!
Many thanks!
John
Jitter using Sleep()
Started by ●January 14, 2010
Reply by ●January 14, 20102010-01-14
On 14 Jan, 13:26, "JHague" <john.ha...@motionsimulation.com> wrote:> Questions > --------- > > So, firstly, do you think this delay that occurs every 499 samples, i.e. 1 > second, is due to some regular external event under Windows,Probably.> or could it be > due to my code (e.g. the Sleep() command itself)? > > If it is due to an external event, are there any Windows tools that > diagnose and track down the cause?The OS could be up to just about anything, and you would need some sort of OS-level debugger to find out exactly what is going on. I would be very surprised if that kind of thing is available outside the R&D department at Microsoft.> If it is due to the Sleep() call itself, is this a deterministic jitter > that we can filter out, are there other variants of Sleep() I can use, or > any other ideas? Or is the answer simply: �Yeah, non-realtime OS: just > accept it and move on�?!?!I think you already have your answer... Rune
Reply by ●January 14, 20102010-01-14
Thanks for your reply Rune - appreciate it. Would like to know whether it is due to Sleep() itself, or from an external source. To rule out Sleep(), do you know of an intensive function call I can make instead of Sleep()? Thanks, John
Reply by ●January 14, 20102010-01-14
Thanks for your reply Rune - appreciate it. Would like to know whether it is due to Sleep() itself, or from an external source. To rule out Sleep(), do you know of an intensive function call I can make instead of Sleep()? Thanks, John
Reply by ●January 14, 20102010-01-14
OK, as a follow up, I've replaced my Sleep() with the following, which (on
my machine at least) also lasts approx. 2 ms:
for( int i = 0; i<1250; ++i)
{
std::ostringstream ss;
ss << i;
}
I get similar output with this code: a regular peak/delay of a few ms
every 1 second. So this jitter is not caused by Sleep().
Looks like an external event. Don't know whether sourced from Windows or
another application.
Any further suggestions to track down this jitter would be most welcome!
Thanks, J
Reply by ●January 14, 20102010-01-14
JHague wrote:> OK, as a follow up, I've replaced my Sleep() with the following, which (on > my machine at least) also lasts approx. 2 ms: > > for( int i = 0; i<1250; ++i) > { > std::ostringstream ss; > ss << i; > } > > I get similar output with this code: a regular peak/delay of a few ms > every 1 second. So this jitter is not caused by Sleep(). > > Looks like an external event. Don't know whether sourced from Windows or > another application. > > Any further suggestions to track down this jitter would be most welcome!Shut off all other applications. Then they can't be the cause. Back in the simpler days or 80286, I just disabled the clock interrupt. Windows hangs if you do that, and tries hard not to let you. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
Reply by ●January 14, 20102010-01-14
JHague wrote:>OK, as a follow up, I've replaced my Sleep() with the following, which(on>my machine at least) also lasts approx. 2 ms: > > for( int i = 0; i<1250; ++i) > { > std::ostringstream ss; > ss << i; > } > >I get similar output with this code: a regular peak/delay of a few ms >every 1 second. So this jitter is not caused by Sleep(). > >Looks like an external event. Don't know whether sourced from Windows or >another application. > >Any further suggestions to track down this jitter would be most welcome!I assume you're just doing this for curiosity, or for use in an extremely controlled environment. My first guess is either a piece of hardware interrupting (or heck, if it's once a second, maybe some system clock is being updated), or else a higher priority thread is set to wake up once a second. I'm sure there are other possibilities. You might fool with the performance counters in mmc; there are some good tips on how to use those and what they tell you in the Russinovich/Solomon book (well, I only have the win2k copy; I assume they're still there).
Reply by ●January 14, 20102010-01-14
Gerry, Michael, Thanks for your feedback. We're actaully developing a high-speed motion control machine. The problem is that our motion data is from an application that has to run on Windows XP. Any jitter getting into the system at source has to be dealt with, and the less jitter the better... Some of system is under a realtime environment, but unfortunately not the source data itself. Such is life. I will look into the MMC tool: thanks. John
Reply by ●January 14, 20102010-01-14
Gerry, Michael, Thanks for your feedback. We're actaully developing a high-speed motion control machine. The problem is that our motion data is from an application that has to run on Windows XP. Any jitter getting into the system at source has to be dealt with, and the less jitter the better... Some of system is under a realtime environment, but unfortunately not the source data itself. Such is life. I will look into the MMC tool: thanks. John
Reply by ●January 14, 20102010-01-14
For a giggle, I've set my process to realtime priority; it now reads:
..
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
while( ++counter < 10000 )
{
QueryPerformanceCounter((LARGE_INTEGER *) &sampleTime);
int time = (sampleTime - startTime) * 1000000 / timerRate;
timeUS[counter] = time;
for( int i = 0; i<1250; ++i)
{
std::ostringstream ss;
ss << i;
}
}
I was surprised to find that even _that_ produced the 1 second heartbeat.
Hmmm ....






