Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Higher Resolution then SleepQQ

onkelhotte
New Contributor II
1,143 Views
Hi there,

I want to "slow down" my calculations, so the user can see the results better.

For that I measure the elapsed time and call the sleepqq function for the remaining time [sleepqq(dt-elapsedt ime)] in ms of course.

But now I want to speed it up, something like 2x, 5x, 10x and maximum Intel CPU Power. When using 5x speed, the program should suspend for 10ms, for 10x its 5ms. But sleepqqs resolution is not high enough, so there is no difference between sleepqq(10) and sleepqq(5) or (of course not) for sleepqq(1).

Is there any way to be more precise? I switched to the SleepEx function, there the situation is a little bit better, but not perfect.

In an older question Steve recommend the "Multimedia Timers", but I dont understand how to use them for this purpose.

Im using IVF 11.0.

Thanks in advance,
Markus
0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
1,143 Views
Under Windows look at

QueryPerformanceCounter and QueryPerformanceCounterFrequency.

With these you can get the current CPU "tick" and the tick rate. The tick rate is your CPU clock rate (or FSB clock rate).

Using the Frequency (ticks per second) produce a delta == to the number of ticks to stall. 1us would be the tick rate / 1000000;

The structure of the performance counter contains a union with a quad part. This is usable as-is as an __int64 type variable.

LARGE_INTEGER now, whenok, freq, deltaTicks;

QueryPerformanceFrequency(&freq); // need only be done once
// freq.QuadPart contains ticks per second
// compute desired delta
// 100us =
deltaTicks.QuadPart = (freq.QuadPart / (__int64)1000000) * 100;
...
QueryPerformanceCounter(&now);
whenok.QuadPart = now.QuadPart + deltaTicks;
while(now.QuadPart < whenok.QuadPart)
{
Sleep(0); // or_mm_pause()
QueryPerformanceCounter(&now);
}

Jim Dempsey

View solution in original post

0 Kudos
2 Replies
jimdempseyatthecove
Honored Contributor III
1,144 Views
Under Windows look at

QueryPerformanceCounter and QueryPerformanceCounterFrequency.

With these you can get the current CPU "tick" and the tick rate. The tick rate is your CPU clock rate (or FSB clock rate).

Using the Frequency (ticks per second) produce a delta == to the number of ticks to stall. 1us would be the tick rate / 1000000;

The structure of the performance counter contains a union with a quad part. This is usable as-is as an __int64 type variable.

LARGE_INTEGER now, whenok, freq, deltaTicks;

QueryPerformanceFrequency(&freq); // need only be done once
// freq.QuadPart contains ticks per second
// compute desired delta
// 100us =
deltaTicks.QuadPart = (freq.QuadPart / (__int64)1000000) * 100;
...
QueryPerformanceCounter(&now);
whenok.QuadPart = now.QuadPart + deltaTicks;
while(now.QuadPart < whenok.QuadPart)
{
Sleep(0); // or_mm_pause()
QueryPerformanceCounter(&now);
}

Jim Dempsey

0 Kudos
onkelhotte
New Contributor II
1,143 Views
Thanks Jim for the answer.

This is the Fortran code:


[bash]use ifwin

real(kind=4) fSleepTime   
integer(kind=8) freq, now, whenok, deltaTicks   
logical l   

!Just call once in your code   
l = QueryPerformanceFrequency(loc(freq))
  
!Use this in your waiting routine
fSleepTime = 0.2 !Time in seconds   
deltaTicks = freq * fSleepTime   
l = QueryPerformanceCounter(loc(now))   
whenOk = now + deltaTicks   
do while(now .lt. whenok)   
    l = sleepEx(0, .false.)   
    l = QueryPerformanceCounter(loc(now))   
end do [/bash]

Markus
0 Kudos
Reply