Delay-Wait-Sleep tricks.
Moderator: DosItHelp
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Delay-Wait-Sleep tricks.
Hi to all,
I tried a lot but still have not found a solution.
Does anyone have any idea on how to do a sleep / wait / delay with a resolution of a few hundredths of a second?
Obviously I'm looking for a solution that uses the least amount of CPU while waiting.
It must also have the possibility to be called multiple times without not too heavy delay in the call.
Einstein1969
I tried a lot but still have not found a solution.
Does anyone have any idea on how to do a sleep / wait / delay with a resolution of a few hundredths of a second?
Obviously I'm looking for a solution that uses the least amount of CPU while waiting.
It must also have the possibility to be called multiple times without not too heavy delay in the call.
Einstein1969
Re: Delay-Wait-Sleep tricks.
Since there is no such built-in function in cmd.exe you have to use an external command. What about PING /W? Of course it takes a few hundred milliseconds to load the process (like any other external tool would need as well).
Regards
aGerman
Regards
aGerman
Re: Delay-Wait-Sleep tricks.
It may not be the best solution, but ping with a wait delay seems to be a very common way of doing this. Other solutions may work only in XP or only in 7, or require external utilities, so this is good enough for me.
The basic format is 'ping -n 1 -w <ms> 1.1.1.1', or any other invalid IP address can be used. Replace <ms> with the number of milliseconds to wait (1000 for 1s, 300 for .3s, etc.).
There is some delay implicit in the launching of ping itself, so if you try '-w 1' you're not going to actually get a 1ms delay, you'll get 1+ whatever the delay of launching ping is, probably in the hundredth's of seconds. So there's a lower bound to this approach is what I'm trying to say, but otherwise it's very flexible.
Since you said you're looking for a few hundredths, it's going to depend on how quickly ping launches. I'd use a macro to time how long it takes ping to start, lets say it's 20ms (2 hundredths), then add an appropriate value for 'w' on top of that to get the total delay you need. With that short of a delay though I'm not sure if it will be fast enough for you. I usually use this in the range of tenths of seconds up to tens of seconds...
Edit: It seems I was too slow and cross-posted with aGerman. At least we gave the same advice
The basic format is 'ping -n 1 -w <ms> 1.1.1.1', or any other invalid IP address can be used. Replace <ms> with the number of milliseconds to wait (1000 for 1s, 300 for .3s, etc.).
There is some delay implicit in the launching of ping itself, so if you try '-w 1' you're not going to actually get a 1ms delay, you'll get 1+ whatever the delay of launching ping is, probably in the hundredth's of seconds. So there's a lower bound to this approach is what I'm trying to say, but otherwise it's very flexible.
Since you said you're looking for a few hundredths, it's going to depend on how quickly ping launches. I'd use a macro to time how long it takes ping to start, lets say it's 20ms (2 hundredths), then add an appropriate value for 'w' on top of that to get the total delay you need. With that short of a delay though I'm not sure if it will be fast enough for you. I usually use this in the range of tenths of seconds up to tens of seconds...
Edit: It seems I was too slow and cross-posted with aGerman. At least we gave the same advice
Re: Delay-Wait-Sleep tricks.
At least we gave the same advice
Indeed
Just one thing I'd like to mention:
1.1.1.1 could be a valid IP address. I would rather use an IP address that belongs to a reserved block.
See http://www.rfc-editor.org/rfc/rfc5737.txt
Code: Select all
>nul ping -n 1 -w 5000 192.0.2.0
Regards
aGerman
Re: Delay-Wait-Sleep tricks.
Code: Select all
@echo off
echo %time%
FOR /L %%G in (1 1 10000) do rem nothing
echo %time%
Output
Code: Select all
C:\Users\Squash\Desktop>delay.bat
13:59:50.94
13:59:50.97
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Delay-Wait-Sleep tricks.
Thanks!
This are the problems:
1) I want use few CPU
2) I want misure few hundredths of seconds.
that involve this sub problem: How to misure the CPU usage/load?
For question 2) the problem is that:
Output:
There is a problem with ping?
on windows 7 32 bit
Einstein1969
This are the problems:
1) I want use few CPU
2) I want misure few hundredths of seconds.
that involve this sub problem: How to misure the CPU usage/load?
For question 2) the problem is that:
Code: Select all
@echo off & setlocal EnableDelayedExpansion
For %%t in (5 50 500 1000 1500) do (
set time_idle_ms=%%t
set runs=10
(
set t0=!time!
for /L %%p in (1,1,!runs!) do >nul ping -n 1 -w !time_idle_ms! 192.0.2.0
set t1=!time!
)
for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"
set /a average_time=a*10/runs
echo(Input:!time_idle_ms! ms - Output: Average time !average_time! ms
)
Output:
Code: Select all
Input:5 ms - Output: Average time 473 ms
Input:50 ms - Output: Average time 498 ms
Input:500 ms - Output: Average time 499 ms
Input:1000 ms - Output: Average time 1050 ms
Input:1500 ms - Output: Average time 1500 ms
There is a problem with ping?
on windows 7 32 bit
Einstein1969
Last edited by einstein1969 on 01 Nov 2013 13:46, edited 1 time in total.
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Delay-Wait-Sleep tricks.
Squashman wrote:Code: Select all
@echo off
echo %time%
FOR /L %%G in (1 1 10000) do rem nothing
echo %time%
OutputCode: Select all
C:\Users\Squash\Desktop>delay.bat
13:59:50.94
13:59:50.97
I do not want to wait with total consumption of cpu.
Re: Delay-Wait-Sleep tricks.
Wow you taught me something new this afternoon!
Not only did I verify the results that you posted exactly, but I also seem to have confirmed that ping -w rounds the input down to the closest 500ms interval. This is crazy, I can't believe I never noticed this before. I'm on Win7 64-bit, btw. The company upgraded my XP machine recently, so I can't say whether it used to work in XP or if I've just been blind to the rounding all along. I really hope someone will prove the former before I completely look the fool
>pingtest
Ping -w 600 Elapsed Time: 00:00:00.44
Ping -w 650 Elapsed Time: 00:00:00.49
Ping -w 700 Elapsed Time: 00:00:00.49
Ping -w 750 Elapsed Time: 00:00:00.49
Ping -w 800 Elapsed Time: 00:00:00.49
Ping -w 850 Elapsed Time: 00:00:00.48
Ping -w 900 Elapsed Time: 00:00:00.48
Ping -w 950 Elapsed Time: 00:00:00.48
Ping -w 1000 Elapsed Time: 00:00:01.00
Ping -w 1050 Elapsed Time: 00:00:00.99
Ping -w 1100 Elapsed Time: 00:00:00.98
Ping -w 1200 Elapsed Time: 00:00:00.98
Ping -w 1300 Elapsed Time: 00:00:00.98
Ping -w 1400 Elapsed Time: 00:00:00.98
Ping -w 1500 Elapsed Time: 00:00:01.48
Ping -w 1700 Elapsed Time: 00:00:01.56
Ping -w 1900 Elapsed Time: 00:00:01.48
Ping -w 2100 Elapsed Time: 00:00:01.98
Ping -w 2300 Elapsed Time: 00:00:01.98
Ping -w 2600 Elapsed Time: 00:00:02.48
Ping -w 2900 Elapsed Time: 00:00:02.49
Ping -w 3100 Elapsed Time: 00:00:02.98
Forget everything I said about how "flexible" ping is, it seems it's time to find another technique
Not only did I verify the results that you posted exactly, but I also seem to have confirmed that ping -w rounds the input down to the closest 500ms interval. This is crazy, I can't believe I never noticed this before. I'm on Win7 64-bit, btw. The company upgraded my XP machine recently, so I can't say whether it used to work in XP or if I've just been blind to the rounding all along. I really hope someone will prove the former before I completely look the fool
>pingtest
Ping -w 600 Elapsed Time: 00:00:00.44
Ping -w 650 Elapsed Time: 00:00:00.49
Ping -w 700 Elapsed Time: 00:00:00.49
Ping -w 750 Elapsed Time: 00:00:00.49
Ping -w 800 Elapsed Time: 00:00:00.49
Ping -w 850 Elapsed Time: 00:00:00.48
Ping -w 900 Elapsed Time: 00:00:00.48
Ping -w 950 Elapsed Time: 00:00:00.48
Ping -w 1000 Elapsed Time: 00:00:01.00
Ping -w 1050 Elapsed Time: 00:00:00.99
Ping -w 1100 Elapsed Time: 00:00:00.98
Ping -w 1200 Elapsed Time: 00:00:00.98
Ping -w 1300 Elapsed Time: 00:00:00.98
Ping -w 1400 Elapsed Time: 00:00:00.98
Ping -w 1500 Elapsed Time: 00:00:01.48
Ping -w 1700 Elapsed Time: 00:00:01.56
Ping -w 1900 Elapsed Time: 00:00:01.48
Ping -w 2100 Elapsed Time: 00:00:01.98
Ping -w 2300 Elapsed Time: 00:00:01.98
Ping -w 2600 Elapsed Time: 00:00:02.48
Ping -w 2900 Elapsed Time: 00:00:02.49
Ping -w 3100 Elapsed Time: 00:00:02.98
Forget everything I said about how "flexible" ping is, it seems it's time to find another technique
Re: Delay-Wait-Sleep tricks.
einstein1969 wrote:I do not want to wait with total consumption of cpu.
Are you saying that the FOR command uses 100% of the cpu when it runs.
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Delay-Wait-Sleep tricks.
Squashman wrote:einstein1969 wrote:I do not want to wait with total consumption of cpu.
Are you saying that the FOR command uses 100% of the cpu when it runs.
Yes. On my machine if i use the "FOR ... rem" the CPU is closed to 100% usage (single core)
Re: Delay-Wait-Sleep tricks.
Here is an accurate delay routine, but it uses CPU
@echo off&goto :start
:Delay milliseconds
echo.Delay milliseconds
echo.Delays for the specified # of milliseconds
echo.Always accurate to within 10 milliseconds
echo.Returns error of precision in milliseconds
echo.Requires %%time%% variable in military format to work
exit /b 1
:start
if [%1]==[] goto :Delay Syntax
if /i %1 geq 600000 goto :Delay Syntax
setlocal enableextensions
set correct=0
set /a msecs=%1+5
if /i %msecs% leq 20 set /a correct-=2
set time1=%time: =%
set /a tsecs=%1/1000 2>nul
set /a msecs=(%msecs% %% 1000)/10
for /f "tokens=1-4 delims=:." %%a in ("%time1%") do (
set hour1=%%a&set min1=%%b&set sec1=%%c&set "mil1=%%d"
)
if /i %hour1:~0,1% equ 0 if /i "%hour1:~1%" neq "" set hour1=%hour1:~1%
if /i %min1:~0,1% equ 0 set min1=%min1:~1%
if /i %sec1:~0,1% equ 0 set sec1=%sec1:~1%
if /i %mil1:~0,1% equ 0 set mil1=%mil1:~1%
set /a sec1+=(%hour1%*3600)+(%min1%*60)
set /a msecs+=%mil1%
set /a tsecs+=(%sec1%+%msecs%/100)
set /a msecs=%msecs% %% 100
::check for midnight crossing
if /i %tsecs% geq 86400 set /a tsecs-=86400
set /a hour2=%tsecs% / 3600
set /a min2=(%tsecs%-(%hour2%*3600)) / 60
set /a sec2=(%tsecs%-(%hour2%*3600)) %% 60
set /a err=%msecs%
if /i %msecs% neq 0 set /a msecs+=%correct%
if /i 1%msecs% lss 20 set msecs=0%msecs%
if /i 1%min2% lss 20 set min2=0%min2%
if /i 1%sec2% lss 20 set sec2=0%sec2%
set time2=%hour2%:%min2%:%sec2%.%msecs%
:wait
set timen=%time: =%
if /i %timen% geq %time2% goto :end
goto :wait
:end
for /f "tokens=2 delims=." %%a in ("%timen%") do set num=%%a
if /i %num:~0,1% equ 0 set num=%num:~1%
set /a err=(%num%-%err%)*10
endlocal&exit /b %err%
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Delay-Wait-Sleep tricks.
aGerman wrote:Since there is no such built-in function in cmd.exe you have to use an external command. What about PING /W? Of course it takes a few hundred milliseconds to load the process (like any other external tool would need as well).
Regards
aGerman
Thanks aGerman,
Already in another post you pointed out the startup delay of an external process. But apparently the ping uses much less than a few hundred milliseconds. On my machine the initiation of ping seems to use only 10-15 ms(0.01 seconds). I get 9-10 ms with "start /realtime..."
Code: Select all
...
echo Startup time:
(
set t0=!time!
ping > nul
set t1=!time!
)
call :difftime t0 t1 b
set /a time_ms=b*10
echo(single startup: !time_ms! ms
(
set t0=!time!
for /L %%n in (1,1,100) do ping > nul
set t1=!time!
)
call :difftime t0 t1 b
set /a average_time=b*10/100
echo(100 startup: Average time !average_time! ms
(
set t0=!time!
for /L %%n in (1,1,100) do c:\windows\system32\ping.exe > nul
set t1=!time!
)
call :difftime t0 t1 b
set /a average_time=b*10/100
echo(100 startup with path: Average time !average_time! ms
(
set t0=!time!
for /L %%n in (1,1,100) do start "" /REALTIME /WAIT /B c:\windows\system32\ping.exe > nul
set t1=!time!
)
call :difftime t0 t1 b
set /a average_time=b*10/100
echo(100 startup with path + start /REALTIME: Average time !average_time! ms
result:
Code: Select all
Startup time:
single startup: 20 ms
100 startup: Average time 14 ms
100 startup with path: Average time 13 ms
100 startup with path + start /REALTIME: Average time 9 ms
Einstein1969
Re: Delay-Wait-Sleep tricks.
If you look at my reply above, the problem with ping is not that it takes long to start, but that it rounds the wait input to 500ms intervals. At least on Win7 as you and I both found out. It'd be great if someone could verify/disprove that on WinXP, since I'm shocked I've never noticed it before.
Re: Delay-Wait-Sleep tricks.
Post your pingtest code...
Re: Delay-Wait-Sleep tricks.
Sorry foxidrive I was at work when I did the pingtest so I don't have the code here. I first just repeated einstein's test (his code is above) because I couldn't believe his results. I got the same thing he got, and started to suspect the 500ms rounding. So I modified his test with new values to test the resolution, but removed the 10x loop and averaging code.
So my FOR looked something like FOR %%i IN (500 550 600 700 900... 2100 2300 ... 3100). Inside the FOR was just calling time macro, ping, and echo the time result.
I figured it wasn't worth running multiple trials and averaging when it was so clearly rounding everything off to 500ms intervals, but I still find it hard to believe that if XP behaved that way I'd have never caught it...
So my FOR looked something like FOR %%i IN (500 550 600 700 900... 2100 2300 ... 3100). Inside the FOR was just calling time macro, ping, and echo the time result.
I figured it wasn't worth running multiple trials and averaging when it was so clearly rounding everything off to 500ms intervals, but I still find it hard to believe that if XP behaved that way I'd have never caught it...