Why is pause function so inaccurate on Windows?

19 views (last 30 days)
tic;
for k =1:2000, pause(0.0014);
end
toc
This code takes about 2.89 seconds on Linux machine but 30 seconds on windows. Tested on different machines. Is there a bug in the pause function?

Accepted Answer

dpb
dpb on 2 Jan 2023
pause uses the Windows default system timer which is 15 msec unless a high resolution timer has been user-created/set. So, your 2000 iterations * 15 msec/iteration --> 30 sec as you observed.
See <MS High-resolution timers> for the poop from MS on the Win API.
I've not looked to see if TMW has implemented any hooks into the higher-resolution timer or not...although I think maybe tic...toc might use one, but they don't reset the OS system clock.
  15 Comments
dpb
dpb on 6 Jan 2023
The system time, yes; but one can set a high resolution timer as noted earlier; note also that tic;toc don't suffer the same problem...
Bruno Luong
Bruno Luong on 6 Jan 2023
Edited: Bruno Luong on 6 Jan 2023
tic/toc merely inquires time, it is a passive command, in Windows if it it use CPU counter it is very accurate. Of course the current (MATLAB= thread can be suspend by the OS in between tic and toc to run something else in higher priroty.
pause on the other hand suspends the current thread at certain time, (in some sense an active command that performs a passive task) s and this must goes through system scheduler to handle hundred other processes on the computer.
If the purpose is to wait certain time I might propose this as alternative, but it is NOT suspense the tasks and CPU is still eating CPU unlike pause:
t0=tic;
n = 1000;
t = zeros(1,n);
dtin = 0.0014;
for i=1:n
mypause(dtin);
t(i) = toc(t0);
end
os = 'windows11-22H2';
histogram(diff(t))
xline(dtin, '-', sprintf('dtin=%g', dtin));
title(['R' version('-release') ' - ' os])
function mypause(t)
% Like pause(t) but overcome the resolution of 15 ms on certain Windows OS
% NOTE: current thread is not really suspended
tms = floor(t*1000);
if tms == 0
pause(t);
else
t0=tic;
for i=1:tms
pause(0.001);
telapse = toc(t0);
if telapse > t
break
end
end
tremain = t-telapse;
if tremain > 0
pause(min(tremain,0.001)); % pause only accurate less than 1ms
end
end
end

Sign in to comment.

More Answers (1)

Bruno Luong
Bruno Luong on 6 Jan 2023
Edited: Bruno Luong on 6 Jan 2023
The reason is that Windows task scheduler resolution is the order of 15 ms in some recent versions.
I create some C mex and call Windows API
Sleep(tms);
and
MsgWaitForMultipleObjects(0, NULL, FALSE, tms, 0x0010);
Both exibit the 15 ms resolutions observed by pause() discussed above.
I find this article also observe the 15 ms behavioir on Windows https://randomascii.wordpress.com/2020/10/04/windows-timer-resolution-the-great-rule-change/

Tags

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!