Possible inefficiency in WaitForSingleObject, from benchmarking against Sleep()

265 views Asked by At

I benchmarked the various Windows sleep APIs on Windows 8.1, and found what appears to be an inefficiency in WaitForSingleObject().

Assuming the periodic timer has been set to 1 ms through timeBeginPeriod(1), here are their performances:

  • Sleep(n), n a positive integer, gives a sleep of duration [n, n+1]. 0 is a special case.

  • NtDelayExecution(x), x a nonnegative real number, gives a sleep of duration [x, x+1]. By not rounding x to the nearest millisecond, it is more precise than Sleep(). It also works with x<1, and Sleep() does not.

  • CreateWaitableTimer(x) behaves like Sleep(floor(x)), or if x is already an integer, doubles its error to [x-1, x+1]. (Thus, it is strictly worse.)

  • WaitForSingleObject(n) waits for a period between [n-1, n+1]. The distribution is biased towards n-1 and is roughly triangular, so values are more common in the lower half and less common near the border.

  • NtWaitForSingleObject(x) waits for a period between [x-1, x+1]. The distribution is biased towards x-1 and is roughly triangular, so values are more common in the lower half and less common near the border.

If the periodic timer is set through NtSetTimerResolution() to a value other than 1 ms, such as 0.5 ms, or to 2 ms, then all the wakeup points are multiplied by this value, and hence so are the distributions (so, waiting periods are twice as precise if the timer is set to 0.5 ms, with the caveat of extra power consumption).

The fact that WaitForSingleObject() shares properties with Sleep() - its reliance on the timer resolution and its distribution of values - makes me believe that it shares a underlying source. However, the skew to a triangular distribution means there is extra noise or rounding in an intermediate step, which is spreading out the possible results. NtWaitForSingleObject() also parallels NtDelayExecution() with the same issue.

Is there a way to achieve the full accuracy of the underlying source, bypassing this middle-man error, using documented or undocumented APIs?

0

There are 0 answers