If I have an empty while loop in my code such as:
while(true);
It will drive the processor usage up to about 25%. However if I do the followin
Because the Sleep is basically telling the processor to switch contexts and let some other programs get more CPU time.
I am going to guess that you have four cores on your multicore processor, which would explain the 25%, as you are completely tying up one processor doing your busy loop, as the only break in it is when the application is delayed so another application can run (but that may not happen depending on the load).
When you put a thread to sleep then it allows the OS to do other operations, and it knows when, as a minimum, to come back and wake up the thread, so it can continue it's work.
You have a quad-core machine, am I right? If so,
while(true);
is actually using 100% of one of your cores.
To the operating system, it seems your program has a lot of work to do. So the operating system lets the program go ahead with this work. It can't tell the difference between your program number crunching like crazy, and doing a useless infinite loop.
Sleep(1);
on the other hand explicitly tells the operating system that your have no work to do for the next millisecond. The OS will thus stop running your program and let other programs do work.
An empty loop isn't actually empty. A loop in itself is at least a comparison and a jump back to the comparison. Modern CPUs can do millions of these operations per second.
The sleep statement in the second loop relinquishes control to the operating system for at least 1 millisecond. In this state, the application is effectively halted and does not continue processing. The result of halting for x amount of time reduces the number of comparisons, and hence the % of cpu clock cycles the cpu can execute per second.
Concerning the 25%, Intel processors that support Hyperthreading or multi core processors might taint the performance statistics. The empty loop is effectively topping off at least one processor core.
Back in the day when multicore CPUs didn't exist, the users did have the need for multi processing/tasking. There are a couple of ways the illusion of running multiple processes at the same time was achieved.
One way was to design application in such a way that they needed to relinquish control to the system ever so often, as to let other processes run for a while. This was the case in the old Windows versions. If a given application was badly designed so that it didn't relinquish control, or got stuck in an endless loop, your entire PC effectively froze up.
Needless to say this wasn't the best way, and it was replaced by preemptive multitasking. Here a Programmable Interrupt Timer is instructed to interrupt the running process at a given interval to execute some scheduler code that lets the other processes have a go.
Because you're keeping the processor busy evaluating the loop over annd over.
Using Sleep actually lets other threads execute on the CPU and along with a very short context switch looks as if the CPU is free for a short while.
Because that would run instructions all the time.
Normal programs don't madly run instructions all the time.
For instance, GUI programs just sit idle waiting for events, (such as keyboard input),
Note: sitting idle != while(true);
They only run instructions when events arrive, and the event-handling code is usually small and runs very quickly, (otherwise, the program will appear to be not-responding). Imagine your app gets 5 keystrokes per second, how much CPU time would it take?
That's why normal processes don't take that much CPU.
Now, earlier I said that sitting idle is not the same as an infinite empty loop. Why is that? Sitting idle means telling the OS that you don't have anything to run.
An infinite loops actually is something to run (a repeating jump instruction).
On the other hand, having nothing to run means basically that the OS won't even bother giving you any processor time at all, even if it's your turn.
Another example where programs sit idle is loading files: when you need to load a file, you basically send a signal to the disk and wait for it to find the data and load it into memory. While the data is being loaded (several milliseconds), the process just sits idle, doing nothing.
Yet another instance of a process sitting idle, is Sleep(1)
, here it's explicitly telling the OS not to give it any cpu-time before the specified time has passed.