Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sleep for a few microseconds

Consider the following code:

#include <stdio.h>
#include <time.h>
#include <math.h>

// Compile with gcc -lrt -lm -o test_clock test_clock.c

#define CLOCK CLOCK_MONOTONIC

int main(int argc, char** argv) {
    double temp, elapsed;
    int j;
    struct timespec requestStart, requestEnd, req;

    // Pseudo-sleep
    clock_gettime(CLOCK, &requestStart);
    temp = 0;
    for(j=0; j < 40; j++)
        temp += sin(j);
    clock_gettime(CLOCK, &requestEnd);
    elapsed = ( requestEnd.tv_sec - requestStart.tv_sec ) / 1e-6
                 + ( requestEnd.tv_nsec - requestStart.tv_nsec ) / 1e3;
    printf("Elapsed: %lf us\n", elapsed);

    // Nanosleep
    clock_gettime(CLOCK, &requestStart);
    req.tv_nsec = 5000;
    req.tv_sec = 0;
    clock_nanosleep(CLOCK, 0, &req, NULL);
    clock_gettime(CLOCK, &requestEnd);
    elapsed = ( requestEnd.tv_sec - requestStart.tv_sec ) / 1e-6
                 + ( requestEnd.tv_nsec - requestStart.tv_nsec ) / 1e3;

    printf("Elapsed: %lf us\n", elapsed);

}

On my 2.6.32 system, the result is

Elapsed: 5.308000 us
Elapsed: 69.142000 us

I agree that this is most likely because nanosleep() asks the kernel to reschedule the process. How can I avoid this? I want to keep ownership of the CPU and just idle around for a precise amount of time.

like image 570
Nikratio Avatar asked Feb 13 '11 20:02

Nikratio


3 Answers

If you want your application to be able to "sleep" as precisely as possible, first put your application in realtime conditions

  • use a realtime scheduler class for your program / thread : SCHED_FIFO or SCHED_RR
  • elevate your program / thread priority
  • and if you're going to "sleep" for less than the minimum amount the kernel is going to handle, manually busywait

Have a look at http://www.drdobbs.com/184402031

And this other question: nanosleep high cpu usage?

like image 87
Yann Droneaud Avatar answered Sep 22 '22 20:09

Yann Droneaud


The OS scheduler is not going to do anything like "oh, take this thread off the processor for exactly 86 clock cycles then put it back on".

You give up the processor, you've given up the processor. The OS will put you back on when it feels like it. Chances are you'll have to wait until whatever else is running gives up the processor before you can sneak back on.

like image 26
Anon. Avatar answered Sep 22 '22 20:09

Anon.


Well, you'll have to learn to live with it since the man page states, in part: the actual time slept may be longer, due to system latencies and possible limitations in the timer resolution of the hardware :-)

Now as to the answer to your question, my best guess is that it's because your first loop is running in-process. In other words, there are no context switches involved since you're running the CPU flat out and you will be doing all that work within your 100ms quanta given to you by the scheduler.

However, there's a good chance that nanosleep will switch you out since you are explicitly asking to be put to sleep. It won't be so inefficient as to just put your process in a tight while loop until the duration is over :-)

That means you're subject to all the vagaries of the scheduler including the fact that another process may totally use up its quanta, hence your process may be out of there for 100ms at least. On a heavily-enough loaded system, it could be out for quite a while.

like image 31
paxdiablo Avatar answered Sep 22 '22 20:09

paxdiablo