Jérôme
Jérôme

Reputation: 2720

How to do an active sleep?

I am running some profiling tests, and usleep is an useful function. But while my program is sleeping, this time does not appear in the profile.

eg. if I have a function as :

void f1() {
    for (i = 0; i < 1000; i++)
        usleep(1000);
}

With profile tools as gprof, f1 does not seems to consume any time.

What I am looking is a method nicer than an empty while loop for doing an active sleep, like:

while (1) {
    if (gettime()  == whatiwant)
        break;
}

Upvotes: 1

Views: 1301

Answers (7)

Mike Dunlavey
Mike Dunlavey

Reputation: 40669

This is the kind of confusion you get with gprof, since what you care about is wall-clock time. I use this.

Upvotes: 0

J. Polfer
J. Polfer

Reputation: 12481

I assume you want to find out the total amount of time (wall-clock time, real-world time, the time you are sitting watching your app run) f1() is taking, as opposed to CPU time. I'd investigate to see if gprof can give you a wall-clock-time instead of a processing-time.

I imagine it depends upon your OS, but the reason you aren't seeing usleep as taking any process time in the profile is because it technically isn't using any during that time - other running processes are (assuming this is running on a *nix platform).

Upvotes: 2

Ariel
Ariel

Reputation: 5830

That's why it's important when profiling to look at the "Switched Out %" time. Basically, while your function's exclusive time may be little, if it performs e.g. I/O, DB, etc, waiting for external resources, then "Switched Out %" is the metric to watch out.

Upvotes: 0

Keith Smith
Keith Smith

Reputation: 3676

What kind of a system are you on? In UNIX-like systems you can use setitimer() to send a signal to a process after a specified period of time. This is the facility you would need to implement the type of "active sleep" you're looking for.

Set the timer, then loop until you receive the signal.

Upvotes: 2

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 247969

for (int i = i; i < SOME_BIG_NUMBER; ++i);

The entire point in "sleep" functions is that your application is not running. It is put in a sleep queue, and the OS transfers control to another process. If you want your application to run, but do nothing, an empty loop is a simple solution. But you lose all the benefits of sleep (letting other applications run, saving CPU usage/power consumption)

So what you're asking makes no sense. You can't have your application sleep, but still be running.

Upvotes: 1

IlDan
IlDan

Reputation: 6869

Because when you call usleep the CPU is put to work to something else for 1 second. So the current thread does not use any processor resources, and that's a very clever thing to do.

An active sleep is something to absolutely avoid because it's a waste of resources (ultimately damaging the environment by converting electricity to heat ;) ).

Anyway if you really want to do that you must give some real work to do to the processor, something that will not be factored out by compiler optimizations. For example

for (i = 0; i < 1000; i++)
    time(NULL);

Upvotes: 2

Goz
Goz

Reputation: 62323

AFAIK the only option is to do a while loop. The operating system generally assumes that if you want to wait for a period of time that you will want to be yielding to the operating system.

Being able to get a microsecond accurate timer is also a potential issue. AFAIK there isn't a cross-platform way of doing timing (please someone correct me on this because i'd love a cross-platform sub-microsecond timer! :D). Under Win32, You could surround a loop with some QueryPerformanceCounter calls to work out when you have spent enough time in the loop and then exit.

e.g

void USleepEatCycles( __int64 uSecs )
{
    __int64 frequency;
    QueryPerformanceFrequency( (LARGE_INTEGER*)&frequency );
    __int64 counter;
    QueryPerformanceCounter( (LARGE_INTEGER*)&counter );

    double dStart = (double)counter / (double)frequency;
    double dEnd   = dStart;
    while( (dEnd - dStart) < uSecs )
    {
        QueryPerformanceCounter( (LARGE_INTEGER*)&counter );
        dEnd = (double)counter / (double)frequency;
    }
}

Upvotes: 0

Related Questions