Why is pause function so inaccurate on Windows?

조회 수: 22 (최근 30일)
Nadatimuj
Nadatimuj 2023년 1월 2일
편집: Walter Roberson 2023년 1월 30일
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?

채택된 답변

dpb
dpb 2023년 1월 2일
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
dpb
dpb 2023년 1월 6일
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 2023년 1월 6일
편집: Bruno Luong 2023년 1월 6일
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

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Bruno Luong
Bruno Luong 2023년 1월 6일
편집: Bruno Luong 2023년 1월 6일
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/

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

태그

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by