Nanosleep High CPU Usage

CPU high usage of the usleep on Cent OS 6.3

You're correct, it has to do with the kernel config. usleep(1) will try to sleep for one microsecond. Before high resolution timers, it was not possible to sleep for less than a jiffy (in your case HZ=1000 so 1 jiffy == 1 millisecond).

On CentOS 5.3 which does not have these high resolution timers, you would sleep between 1ms and 2ms[1]. On CentOS 6.3 which has these timers, you're sleeping for close to one microsecond. That's why you're using more cpu on this platform: you're simply polling your task list 500-1000 times more.

If you change the code to usleep(1000), CentOS 5.3 will behave the same. CentOS 6.3 cpu time will decrease and be in the same ballpark as the program running on CentOS 5.3

There is a full discussion of this in the Linux manual: run man 7 time.

Note that your code should use condition variables instead of polling your task list at a certain time interval. That's a more efficient and clean way to do what you're doing.

Also, your main should really join the threads instead of just sleeping for 14 seconds.

[1] There is one exception. If your application was running under a realtime scheduling policy (SCHED_FIFO or SCHED_RR), it would busy-wait instead of sleeping to sleep close to the right amount. But by default you need root privileges

Does sleep/nanosleep work by utilizing a busy wait scheme?

Exact implementation is not guaranteed here but you can expect some properties.

Usually sleep (3) is quite inaccurate and as Linux 'man sleep 3' states could be even implemented using SIGALM (signals). So it is definitely not about performance. It is definitely not about spin locks too so cannot be CPU intensive.

nanosleep is quite different animal which could be implemented even using spinlocks. Which is more important, at least in Linux nanosleep man is in section 2 which stands it is system call so at least it should include switch to kernel mode. Do you really need its high resolution?

UPDATE

As I see your comment I do recommend select() usage as man select 3 states:

   #include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int
main(void)
{
fd_set rfds;
struct timeval tv;
int retval;

/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);

/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;

retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */

if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds) will be true. */
else
printf("No data within five seconds.\n");

exit(EXIT_SUCCESS);
}

It is proven mechanics if you need to sleep in thread for some event and this event could be linked to file descriptor.

nanosleep - need low resolution

The previous behaviour (sleeping for a nanosecond with a 250Hz interrupt frequency) would, in average, sleep for 1/500th of a second.

If you want approximately the same behaviour as before, you can simply sleep for 1/500th of a second, which is 2,000,000 nanoseconds.

nanosleep - need low resolution

The previous behaviour (sleeping for a nanosecond with a 250Hz interrupt frequency) would, in average, sleep for 1/500th of a second.

If you want approximately the same behaviour as before, you can simply sleep for 1/500th of a second, which is 2,000,000 nanoseconds.



Related Topics



Leave a reply



Submit