简体   繁体   中英

Abandoning CPU time

Is it possible in C/C++, to "abandon" thread's CPU time? For example:

void wait(int s) //Low cpu usage
{
 int tmp = time();
 while(tmp + CLOCKS_PER_SEC * s > time())
  __AbandonCPUTime();
  //Tell cpu to do sth else.
}

I've tried Sleep(0), but it doesn't work.

Look at C++11's:

#include <thread>
std::this_thread::yield();

Your CPU may support the _mm_pause() intrinsic ( __asm__("pause") for gcc) which may or may not help you.

Otherwise you'll be looking at OS specific functions: sched_yield() for pthreads on Linux, or SwitchToThread() on Windows

Edit to answer the question more directly: you should either wait for something (WaitForSingleObject or GetMessage or some equivalent) or, if there isn't an event that you can wait for Sleep for some non-zero number of milliseconds.

Sleep(0) will typically return immediately so you still burn lots of energy and drain the user's battery or raise their power bill. Sleep(1) is still a hack but it is many orders of magnitude better than Sleep(0), _mm_pause(), sched_yield(), or SwitchToThread().

Sleep(0) on Windows will yield to another thread of the same priority if there is one that is waiting to run. This is rarely useful because, especially with dynamic adjustment of thread priorities, you can never tell whether there is another thread of the same priority. Sleep(0) generally won't switch to a thread of higher priority because that thread (being higher priority) would already be running. And it won't switch to a thread of lower priority, because it won't. SwitchToThread has similar problems.

_mm_pause() tells the CPU to go idle for a few cycles. This reduces power consumption and on a hyperthreaded machine lets the other thread on that core run faster. However this isn't something you should normally be doing.

If you want to wake up in n milliseconds then call Sleep(n). Or, better yet, wait on a specific event.

Functions like sched_yield, Sleep(0), and SwitchToThread are all generally bad ideas because they don't tell the OS when you want to run again.

Whatever you do don't busy wait, even with _mm_pause. http://randomascii.wordpress.com/2012/06/05/in-praise-of-idleness/

sched_yield() "causes the calling thread to relinquish the CPU."

http://www.kernel.org/doc/man-pages/online/pages/man2/sched_yield.2.html

FYI, Intel have released two best practices on how to do what you want and it's mostly done via the use of _mm_pause() . Note that their gen 6 wait cycle times have been increased deliberately, so what you need is a combination of what's described in the following articles:

https://software.intel.com/en-us/articles/a-common-construct-to-avoid-the-contention-of-threads-architecture-agnostic-spin-wait-loops

https://software.intel.com/en-us/articles/benefitting-power-and-performance-sleep-loops

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM