瀏覽代碼

libobs/util: Improve os_sleepto_ns on Windows

Avoid nanosecond abstraction to reduce math operations.

Replace Sleep(0) with YieldProcessor(). We want the thread to remain
scheduled, the current CPU core to do less work, and the hyperthread
sibling to perform better.

Hacky profiling showed maybe 10-25 µs skid reduction per function call.
I think power/performance gains would be hard to measure, so I haven't
tried, but it would be shocking if they got worse.
jpark37 4 年之前
父節點
當前提交
e69f051736
共有 1 個文件被更改,包括 22 次插入19 次删除
  1. 22 19
      libobs/util/platform-windows.c

+ 22 - 19
libobs/util/platform-windows.c

@@ -330,27 +330,30 @@ void os_cpu_usage_info_destroy(os_cpu_usage_info_t *info)
 
 
 bool os_sleepto_ns(uint64_t time_target)
 bool os_sleepto_ns(uint64_t time_target)
 {
 {
-	uint64_t t = os_gettime_ns();
-	uint32_t milliseconds;
-
-	if (t >= time_target)
-		return false;
-
-	milliseconds = (uint32_t)((time_target - t) / 1000000);
-	if (milliseconds > 1)
-		Sleep(milliseconds - 1);
-
-	for (;;) {
-		t = os_gettime_ns();
-		if (t >= time_target)
-			return true;
+	const double freq = (double)get_clockfreq();
+	const LONGLONG count_target =
+		(LONGLONG)((double)time_target * freq / 1000000000.0);
+
+	LARGE_INTEGER count;
+	QueryPerformanceCounter(&count);
+
+	const bool stall = count.QuadPart < count_target;
+	if (stall) {
+		const DWORD milliseconds = (DWORD)(
+			((count_target - count.QuadPart) * 1000.0) / freq);
+		if (milliseconds > 1)
+			Sleep(milliseconds - 1);
+
+		for (;;) {
+			QueryPerformanceCounter(&count);
+			if (count.QuadPart >= count_target)
+				break;
 
 
-#if 0
-		Sleep(1);
-#else
-		Sleep(0);
-#endif
+			YieldProcessor();
+		}
 	}
 	}
+
+	return stall;
 }
 }
 
 
 void os_sleep_ms(uint32_t duration)
 void os_sleep_ms(uint32_t duration)