summaryrefslogtreecommitdiffstats
path: root/Whisper/Utils/DelayExecution.cpp
diff options
context:
space:
mode:
authorKonstantin <const@const.me>2023-01-21 21:23:08 +0100
committerKonstantin <const@const.me>2023-01-21 21:23:08 +0100
commitcacec67bb649702db7a877de1b6482a46123f175 (patch)
tree07456739a57274cfb8cf6750d2acd480b23d0de1 /Whisper/Utils/DelayExecution.cpp
parent040281bccc424341c964788aa7ca17876a5ac6a4 (diff)
Experimental, alternative busy wait implementation
Disabled with a `constexpr` flag because on a desktop with discrete GPU this slowed down by about 20%. But the CPU load is about zero. Need to test on iGPUs, thermal shenanigans might make a difference there.
Diffstat (limited to 'Whisper/Utils/DelayExecution.cpp')
-rw-r--r--Whisper/Utils/DelayExecution.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/Whisper/Utils/DelayExecution.cpp b/Whisper/Utils/DelayExecution.cpp
new file mode 100644
index 0000000..d238e53
--- /dev/null
+++ b/Whisper/Utils/DelayExecution.cpp
@@ -0,0 +1,66 @@
+#include "stdafx.h"
+#include "DelayExecution.h"
+
+namespace
+{
+ constexpr bool useHighRezTimer = false;
+
+ constexpr int64_t sleepMicroseconds = 200;
+
+ inline HRESULT sleepImpl( HANDLE timer )
+ {
+ constexpr int64_t sleepTicks = sleepMicroseconds * 10;
+
+ LARGE_INTEGER li;
+ // Negative values indicate relative time
+ li.QuadPart = -sleepTicks;
+ if( !SetWaitableTimerEx( timer, &li, 0, nullptr, nullptr, nullptr, 0 ) )
+ return getLastHr();
+ const DWORD res = WaitForSingleObject( timer, 50 );
+ if( res == WAIT_OBJECT_0 )
+ return S_OK;
+ if( res == WAIT_FAILED )
+ return getLastHr();
+ return E_FAIL;
+ }
+}
+
+void DelayExecution::sleepOnTheTimer( const DelayExecution& delay )
+{
+ HRESULT hr = sleepImpl( delay.timer );
+ if( SUCCEEDED( hr ) )
+ return;
+ logWarningHr( hr, u8"DelayExecution.sleepOnTheTimer" );
+}
+
+void DelayExecution::spinWait( const DelayExecution& )
+{
+ for( size_t i = 0; i < 1024; i++ )
+ _mm_pause();
+}
+
+void DelayExecution::sleep( const DelayExecution& )
+{
+ Sleep( 0 );
+}
+
+DelayExecution::DelayExecution()
+{
+ if constexpr( useHighRezTimer )
+ {
+ constexpr DWORD flags = CREATE_WAITABLE_TIMER_HIGH_RESOLUTION;
+ HANDLE h = CreateWaitableTimerEx( nullptr, nullptr, flags, TIMER_ALL_ACCESS );
+ if( nullptr != h )
+ {
+ timer.Attach( h );
+ pfn = &sleepOnTheTimer;
+ return;
+ }
+
+ const HRESULT hr = getLastHr();
+ logWarningHr( hr, u8"CreateWaitableTimerEx" );
+ }
+
+ pfn = &spinWait;
+ // pfn = &sleep;
+} \ No newline at end of file