1

One has blocking calls whenever the CPU is waiting for some system to respond, e.g. waiting for an internet request. Is the CPU literally wasting time during these calls (I don't know whether there are machine instructions other than no-op that would correspond to the CPU literally wasting time). If not, what is it doing?

3 Answers3

3

Basically, the kernel maintains run queues or something similar to schedule threads. Each thread receives a time slice where it gets to execute until it expires or it volontarily yields its slice. When a thread yields or its slice expires, the scheduler decides which thread gets to execute next.

A blocking system call would result in a yield. It would also result in the thread being removed from the run queue and placed in a sleep/suspend queue where it is not eligible to receive time slices. It would remain in the sleep/suspend queue until some critiera is met (e.g. timer tick, data available on socket, etc.). Once the criteria is met, it'd be placed back into the run queue.

Sleep(1); // Yield, install a timer, and place the thread in a sleep queue.

As long as there are tasks in any of the run queues (there may be more than one, commonly one per processor core), the scheduler will keep handing out time slices. Depending on scheduler design and hardware constraints, these time slices may vary in length.

When there are no tasks in the run queue, the core can enter a powersaving state until an interrupt is received.

In essence, the processor never wastes time. Its either executing other threads, servicing interrupts or in a powersaving state (even for very short durations).

haste
  • 1,441
  • 1
  • 10
  • 21
3

The thread is simply skipped when the operating system scheduler looks for work to hand off to a core. With the very common outcome that nothing needs to be done. The processor core then executes the HLT instruction.

In the HALT state it consumes (almost) no power. An interrupt is required to bring it back alive. Most typically that will be the clock interrupt, it ticks 64 times per second by default. It could be a device interrupt. The scheduler then again looks for work to do. Rinse and repeat.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

While a thread is blocked, especially if it is blocked on an efficient wait object that puts the blocked thread to sleep, the CPU is busy servicing other threads in the system. If there are no application threads running, there is always system threads running. The CPU is never truly idle.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I asked this question in part because I want to make some code as efficient as possible. Does this mean that if your application has multiple threads, at least some of which are not blocked, then there are no gains to be had from using nonblocking calls (since blocking calls would just cause a context switch to one of your other non-blocked threads)? –  Oct 31 '13 at 20:57
  • @JohnRobertson This would depend highly on the nature of the program. For example, if you are blocking on socket A until its readable, then you cannot service socket B from the same thread, i. e. the thread is just spending time in a sleep queue and won't be scheduled again for an unknown amount of time. You'll have added overhead from context switches and memory footprint by servicing one socket per thread. – haste Oct 31 '13 at 21:28
  • @John *"As efficient as possible"* by itself doesn't mean much. Efficiency with respect to what? Performance? Power consumption? Usability? Memory consumption? You have to decide. A profiler will guide you. – IInspectable Oct 31 '13 at 23:06