Why is pause function so inaccurate on Windows?

21 ビュー (過去 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 Center および File ExchangeLogical についてさらに検索

タグ

製品


リリース

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by