News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Hi resolution Sleep

Started by jj2007, January 23, 2019, 12:27:50 PM

Previous topic - Next topic

jj2007

Credits go to deltarho 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?

sinsi

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


jj2007

Oops, so the "magic" is not a constant. A calibration would be needed then. Thanks :icon14:

Siekmanski

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.
Creative coders use backward thinking techniques as a strategy.

jj2007

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).

Siekmanski

Don't know exactly, worth investigating.  :biggrin:
I'll write something tonight so we can test it further.
Creative coders use backward thinking techniques as a strategy.

TimoVJL

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;
}
May the source be with you

Siekmanski

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
Creative coders use backward thinking techniques as a strategy.

hutch--

I think you will always have limitations due to ring 0 task switching.

Siekmanski

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.
Creative coders use backward thinking techniques as a strategy.

zedd151


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