Using a for-loop or sleeping to wait for short intervals of time

I need to wait for short intervals of time in my program, but I really don't want to include unistd.h just to use sleep, so I'm doing it this way:

int main()
{
for(int i=0; i<=100000000000; i++); // <----- note that the loop doesn't do anything
return 0;
}


I do this when I don't really have a specific interval to set for sleep.

Is there anything wrong with this? Would this harm the program in any way?

In C I know that if I did include unistd.h, and that if I used sleep(), that the following code would also make the program wait for a short interval of time:

int main()
{
sleep(2000); //or whatever the number (in milliseconds)
return 0;
}

• – Michael Urman Feb 22 '14 at 15:42
• Do you have any actual reason for not wanting to type "#include <unistd.h>"? – David Richerby Feb 22 '14 at 21:54
• Using 100000000000 for an int is not very portable, some compilers wouldn't like it. – QuentinUK Feb 23 '14 at 4:09
• I did the same with a program and it nearly killed the computer. Internally, sleep will take the load off the program and put it really to sleep. – Noah Feb 23 '14 at 6:29
• It will likely be optimized out as you wrote it: stackoverflow.com/questions/7083482/… – Ciro Santilli 郝海东冠状病六四事件法轮功 Jun 26 '15 at 6:58

The biggest problem with using a for-loop to do this is that you are wasting CPU power.

When using sleep, the CPU can, in a sense, take a break (hence the name "sleep") from executing your program. This means that the CPU will be able to run other programs that have meaningful work to do while your program waits.

But in the for-loop the CPU continuously have to do work to increase a variable. For what purpose? Nothing. But the CPU doesn't know that. It's told to increase the variable, so that's what it will do. Meanwhile, other programs aren't given as much time to do their work because your program is taking up time.

Please don't waste CPU power, use the sleep approach.

As stated in a comment, additionally, the compiler may optimize out an empty loop, and the attempt to pause may be lost. So either you will waste CPU power, or you will not pause at all.

• In addition, the compiler may optimize out an empty loop, and the attempt to pause may be lost – atk Feb 22 '14 at 19:45
• In further addition, if the compiler left it, it would be bad for scheduling, since the scheduler will see for as a long but active process. – OJFord Feb 22 '14 at 23:08

Back in the day, home computers used to have a “turbo” button, which (when activated), made the processor slower. The problem was that games were coded around an input loop that was expected to take a specific number of milliseconds. If the loop was executed faster, the whole game would speed up, becoming unplayable.

Today, computers have vastly different speeds and performance characteristics, so NOPping isn't reliable in any way (will it take half a second? half a year?). Furthermore, compilers are generally free to remove code that doesn't do anything – compiling your snippet under -O3 would hopefully remove that loop.

Don't use an ugly kludge just to achieve better compilation speed. Do it right – consider yourself a code craftsman, not a code monkey (no offense, rolfl).

• No offense taken... ;-) – rolfl Feb 22 '14 at 18:37
• Eh, my computer is fairly recent and have a Turbo button. However it behaves differently, it does a soft overclock on the GPU. – Pierre-Luc Pineault Feb 23 '14 at 5:46

This is called 'busywaiting' or 'spinning', and will work but has the following disadvantages:

1. It will perform 'work' on your program instead of yielding control to OS and other programs - so it doesn't "play nice" with others; on a common computer there are many programs running at the same time that could also like to use that CPU instead.

2. Busywaiting creates unneeded load on CPU, preventing it from idling - this results in extra heat, fan noise and lower battery life on laptop computers or mobile devices.

3. The delay is unpredictable - it will vary greatly depending on the computer and also the compiler, which may "optimize it away" to no delay at all, as other answers noted.

In short - it will function, so if it's a one-off script for your own use then it can be okay, but if it's code meant for production use or something that will need to be maintained in the future, then don't do it this way.

• +1 for the mention of battery impact, a relatively significant issue when so much computing is done on mobile devices these days. – Barmar Feb 23 '14 at 3:26

This technic is called Spinlock or busy waiting. It is implemented for example in Oracle database software to coordinate access to memory structures between different processes (latches).

It seems to be useful if the overhead of sleeping which results from context switching is larger than waste of CPU time when spinning. This is the case if the expected wait time is very short. Very short means some clock cycles and is far less than 2000 ms that you use in your example.

The compiler will not optimize the loop away if it is implemented correctly. This C example using a volatile variable is from busy waiting .

...
volatile int i=0;
...
while (i==0);
...


volatile tells the compiler that the value of the variable i can be changed from outside the current thread and so the compiler does not throw away the while-loop.

Busy waiting is listed as antipattern here. So you should not use it if you are not completely aware of its consequences.

Trying to avoid the inclusion of unistd.h seems not to be a valid reason to use busy waiting.

The other answers here address the specific issues with your loop, and hopefully have convinced you that it is not the right approach. I want to comment on your motivations.

Why do you want to avoid unistd.h? It is entirely reasonable to include a header for just one function, and in the vast majority of cases there is no compelling reason not to.

If you are concerned about portability, just do something like this:

#if defined(__linux__)
#  include <unistd.h>
#elif defined(_WIN32)
#  include <windows.h>
#  define sleep(s) Sleep((s)*1000)
#endif


Then use sleep(seconds) everywhere.

Two big reasons why that's a bad idea:

1. The time spent on a given loop is very dependent on the computer running it. Ever played Quake on a modern computer? The frame rates are through the roof, and I hope that's not a surprise. More powerful computers can perform more calculations in a set time. If your computer takes 10 seconds to complete a loop, a more powerful computer might finish in 5 or less, and an older computer might take significantly longer.

So, couldn't I just do this?

#include <Mmsystem.h> //timeGetTime
void Stall(unsigned long ms)
{
unsigned long start = timeGetTime();
unsigned long passed = 0;
while (passed < ms)
passed = timeGetTime() - start;
}


Yeah, that would ensure that the same time is taken to finish the function. But don't get too excited; I said two big reasons.

2. Sleep functions set your thread in a sort of "do not disturb" state, allowing your operating system to perform other tasks (handling other threads, cleaning up your thread) while your thread daydreams. While a human could look at the line and interpret it as "do nothing", your computer is wasting power blowing through that empty loop as fast as it can.

So, I can do this?

#include <Mmsystem.h> //timeGetTime
#include <WinBase.h> //Sleep
void Stall(unsigned long ms)
{
unsigned long start = timeGetTime();
unsigned long passed = 0;
while (passed < ms)
{
passed = timeGetTime() - start;
Sleep(0);
}
}


Better, but it still wastes CPU resources when it doesn't have to. And if there are no other threads running, Sleep(0) immediately returns to your thread, meaning your CPU is still running at maximum speed.

Conclusion: for most applications, stick with sleep functions.

The biggest single issue with this approach, other than eating processor cycles, is that the for loop will be removed by the optimiser if you enable any level of optimisation in the compiler. Suddenly you find that code that ran just fine in debug mode, stops working.

• That is no really a valid argument against the usage of this technic. If programmed carefully this probleem can be avoided. Here is a discussion about avoiding optimization for a piece of code when using gcc: stackoverflow.com/questions/2219829/… help – miracle173 Feb 23 '14 at 22:02

Avoiding calling certain proper OS API functions just because of reluctance to include an .h-file is not a fair tradeoff.

You have to include a .h-file with OS API calls or use assembler instructions. It depends on whether you wish to wait for some event to occur e.g. a file finished writing or data finished sending via a socket. In this case, it’s better to call an OS API that simply waits for the event to occur. If you need to just wait a certain amount of time, it also depends on how long do you need to wait. If you need to wait up to about 50 thousands of CPU cycles, then use a combination of PAUSE and RDTSC instruction, call RDTSC once after calling PAUSE about 500 times. If you need delays longer then 50 thousands of CPU cycles, create a waitable high-resolution timer and wait for it. For windows, there is a function CreateWaitableTimer. You can find an example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms687008(v=vs.85).aspx

If you need to wait at least 1 millisecond or more, you can just call Sleep(). But make sure you call sleep with at least 1 millisecond parameter, don’t call Sleep(0) since it will not let CPU rest while you are waiting.