I would like to wait on an event in my app which supposed to happen immediately, so I don't want to put my thread on wait and wake it up later.
I wonder what are the difference between using Sleep(0)
and hardware pause instruction.
I cannot see any differences of cpu utilization for the following program. My question isn't about power saving considerations.
#include <iostream>
using namespace std;
#include <windows.h>
bool t = false;
int main() {
while(t == false)
{
__asm { pause } ;
//Sleep(0);
}
}
Windows Sleep(0) vs The PAUSE instruction
Let me quote from the Intel 64 and IA-32 Architectures Optimization Reference Manual.
Example #1. Unoptimized Sleep Loop
Example #2. Power Consumption Friendly Sleep Loop Using PAUSE
Pause Latency in Skylake Microarchitecture
You can find more information on this issue in the "Intel 64 and IA-32 Architectures Optimization Reference Manual" and "Intel 64 and IA-32 Architectures Software Developer’s Manual", along with the code samples.
My Opinion
It is better make program logic flow in such a way that neither Sleep(0) nor the PAUSE instruction are ever needed. In other words, avoid the “spin-wait” loops altogether. Instead, use high-level synchronization functions like
WaitForMultipleObjects()
,SetEvent()
, and so on. Such high-level synchronization functions are the best way to write the programs. If you analyze available tools (at your disposition) from the terms of performance, efficiency and power saving - the higher-level functions are the best choice. Although they also suffer from expensive context switches and ring 3 to ring 0 transitions, these expenses are infrequent and are more than reasonable, compared to what you would have spent in total for all the “spin-wait” PAUSE cycles combined, or the cycles with with Sleep(0).On a processor supporting hyper-threading, “spin-wait” loops can consume a significant portion of the execution bandwidth of the processor. One logical processor executing a spin-wait loop can severely impact the performance of the other logical processor. That's why sometimes disabling hyper-threading may improve performance, as have been pointed out by some people.
Consistently polling for devices or file or state changes in the program logic workflow can cause the computer to consume more power, to put stress on memory and the bus and to provide unnecessary page faults (use the Task Manager in Windows to see which applications produce most page faults while in the idle state, waiting for user input in the background - these are most inefficient applications since they are using the poling above mentioned). Minimize polling (including the spin-loops) whenever possible and use an event driven ideology and/or a framework if available - this is the best practice that I highly recommend. You application should literally sleep all the time, waiting for multiple events set up in advance.
A good example of an event-driven application is Nginx, initially written for unix-like operating systems. Since the operating systems provide various functions and methods to notify your application, use these notifications instead of polling for device state changes. Just let your program to sleep infinitely until a notification will arrive or a user input will arrive. Using such a technique reduces the overhead for the code to poll the status of the data source, because the code can get notifications asynchronously when status changes happen.