The MASM Forum

General => The Workshop => Topic started by: jj2007 on January 23, 2019, 12:27:50 PM

Title: Hi resolution Sleep
Post by: jj2007 on January 23, 2019, 12:27:50 PM
Credits go to deltarho (https://www.freebasic.net/forum/viewtopic.php?f=2&t=27371&p=257539#p257534) 8)

include \masm32\MasmBasic\MasmBasic.inc ; the macro works also with pure Masm32

VeryHiResSleep MACRO msSleep ; milliseconds
  pushad
  rdtsc
  xchg eax, ebx
  mov edi, edx
  push eax
  push edx
  invoke QueryPerformanceFrequency, esp
  fld FP4(msSleep)
  fild qword ptr [esp]
  fmul
  fmul FP4(1.023986) ; magic to compensate whatever
  fistp qword ptr [esp]
  pop eax
  pop edx
  add ebx, eax
  add edi, edx
  .Repeat
rdtsc
  .Until eax>ebx && edx>=edi
  popad
  exitm <>
ENDM

  Init
  Delay 100
  For_ ecx=1 To 100
Delay 1
NanoTimer()
VeryHiResSleep(123.456789)
void NanoTimer(µs)
.if eax>127
PrintLine Str$("%6f\t\t", eax/1000), Str$(ecx)
  .endif
  Next
  Inkey "ok?"
EndOfCode


Expected result:
123.456         1
123.456         2
123.456         3
123.456         4
123.456         5
123.456         6
123.456         7
123.456         8
123.456         9


What do you see?
Title: Re: Hi resolution Sleep
Post by: sinsi on January 23, 2019, 12:41:38 PM
What do I see? This

351.264         1
351.263         2
351.263         6
351.263         7
351.263         8
351.264         17
351.263         18
351.263         19
351.263         34
351.264         35
351.264         36
351.263         43
351.264         44
351.264         45
351.263         53
351.263         54
351.263         55
351.263         65
351.263         66
351.264         67
351.264         88
351.264         89
351.263         90

Title: Re: Hi resolution Sleep
Post by: jj2007 on January 23, 2019, 12:45:25 PM
Oops, so the "magic" is not a constant. A calibration would be needed then. Thanks :icon14:
Title: Re: Hi resolution Sleep
Post by: Siekmanski on January 23, 2019, 07:28:00 PM
532.052         1
532.053         2
532.052         84
532.052         85
ok?

It looks more like a timed stalling than a timed sleep....

Maybe this is an option:

IReferenceClock::GetTime
IReferenceClock::AdviseTime

https://docs.microsoft.com/en-us/windows/desktop/wmformat/ireferenceclock

It's an event driven 100-nanosecond units resolution timer.

I've used it succesful in creating a Timer-Interrupt routine to get the lowest possible latency in DirectSound without wasting system resources.
Title: Re: Hi resolution Sleep
Post by: jj2007 on January 23, 2019, 11:28:04 PM
Quote from: Siekmanski on January 23, 2019, 07:28:00 PMIt looks more like a timed stalling than a timed sleep....

Yes, it's more a joke.

QuoteIReferenceClock::GetTime
IReferenceClock::AdviseTime

https://docs.microsoft.com/en-us/windows/desktop/wmformat/ireferenceclock

It's an event driven 100-nanosecond units resolution timer.

Looks interesting, but I wouldn't be surprised to find NtDelayExecution under the hood. And that one is already used in
Delay until fTime$(s:1, "HH:mm:ss.123") ; use time$(current plus one second).
Title: Re: Hi resolution Sleep
Post by: Siekmanski on January 23, 2019, 11:46:35 PM
Don't know exactly, worth investigating.  :biggrin:
I'll write something tonight so we can test it further.
Title: Re: Hi resolution Sleep
Post by: TimoVJL on January 24, 2019, 06:01:07 AM
Silly small test project with PDB for debugging.
int main(void)
{
    CoInitialize( NULL );
    IReferenceClock* pRefClock;
    HRESULT hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (void**)&pRefClock );
if (pRefClock) {
long long llTime1, llTime2;
DWORD dwCookie;
hr = pRefClock->lpVtbl->GetTime(pRefClock, &llTime1);
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("MyEvent"));
hr = pRefClock->lpVtbl->AdviseTime(pRefClock, llTime1, 10000000, hEvent, &dwCookie);
if (!hr) {
printf("wait...");
WaitForSingleObject(hEvent, INFINITE);
} else printf("error");
hr = pRefClock->lpVtbl->GetTime(pRefClock, &llTime2);
printf("time: %lld\n", llTime2 - llTime1);
    pRefClock->lpVtbl->Release(pRefClock);
}
    CoUninitialize();
    return 0;
}
Title: Re: Hi resolution Sleep
Post by: Siekmanski on January 24, 2019, 08:19:04 AM
IReferenceClock Sleep test.
The results are a bit disappointing for small resolutions....

Resolution: 1.0 second
0.999471650726559 seconds
1.000116704776725 seconds
1.000111326998264 seconds
1.000117542872069 seconds

Resolution: 0.1 seconds
0.099520679304213 seconds
0.099822114263126 seconds
0.099843834900804 seconds
0.099841250773492 seconds

Resolution: 0.01 seconds
0.009674832974582 seconds
0.009806623467508 seconds
0.010794737878697 seconds
0.009871436174151 seconds

Resolution: 0.001 seconds
0.000068374611857 seconds
0.000069771437431 seconds
0.000074450803105 seconds
0.000027447622533 seconds

Resolution: 0.0001 seconds
0.000060063499691 seconds
0.000067326992676 seconds
0.000069352389759 seconds
0.000068234929300 seconds

Resolution: 0.00001 seconds
0.000039320639914 seconds
0.000040088893980 seconds
0.000059853975854 seconds
0.000068095246742 seconds
Title: Re: Hi resolution Sleep
Post by: hutch-- on January 24, 2019, 10:00:58 AM
I think you will always have limitations due to ring 0 task switching.
Title: Re: Hi resolution Sleep
Post by: Siekmanski on January 24, 2019, 10:07:41 AM
Yep, it's a bit of a problem with the timers in windows.
We have to accept it.  :biggrin:

At least we can delay the execution with ~0.00005 seconds which is 20 times shorter than invoke Sleep,1
It can be useful in high performance apps.
Title: Re: Hi resolution Sleep
Post by: zedd151 on January 25, 2019, 06:36:28 AM

123.457         1
123.457         2
123.457         3
123.458         4
123.457         5
123.459         6
123.457         7
123.457         8
123.457         9
123.457         10
123.457         11
123.457         12
123.456         13
123.457         14
123.457         15
123.457         16
123.457         17
123.458         18
123.457         19
123.457         20
123.457         29
123.456         30
123.457         31
123.457         32
123.457         33
123.457         34
123.456         35
123.456         36
123.457         37
123.459         38
123.457         39
123.457         40
123.457         41
123.457         42
123.457         43
123.457         44
123.457         45
123.457         46
123.456         47
123.457         48
123.457         49
123.457         54
123.457         55
123.457         56
123.459         57
123.457         58
123.457         59
123.458         60
123.457         61
123.457         62
123.457         63
123.457         64
123.457         65
123.457         66
123.457         67
123.458         68
123.457         69
123.456         70
123.457         71
123.459         72
123.457         73
123.457         74
123.457         78
123.457         79
123.457         80
123.457         81
123.457         82
123.456         83
123.457         84
123.458         85
123.458         86
123.458         87
123.458         88
123.457         89
123.457         90
123.457         91
123.458         92
123.457         93
123.457         94
123.457         95
123.458         96
123.457         97
123.455         98
ok?


And I thought 'High Resolution Sleep' meant that you slept well, and your dreams were so vivid you thought they were real life in real time. :P