Cent OS 6.3上的usleep的CPU高使用率 [英] CPU high usage of the usleep on Cent OS 6.3

查看:137
本文介绍了Cent OS 6.3上的usleep的CPU高使用率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在cent os 5.3和cent os 6.3上编译以下代码:

I compile the code below on cent os 5.3 and cent os 6.3:

#include <pthread.h>
#include <list>
#include <unistd.h>
#include <iostream>
using namespace std;
pthread_mutex_t _mutex;
pthread_spinlock_t spinlock;

list<int *> _task_list;

void * run(void*);
int main()
{
    int worker_num  = 3;
        pthread_t pids[worker_num];
        pthread_mutex_init(&_mutex, NULL);
        for (int worker_i = 0; worker_i < worker_num; ++worker_i)
        {
                pthread_create(&(pids[worker_i]), NULL, run, NULL);
        }
    sleep(14);
}


void *run(void * args)
{
        int *recved_info;
    long long start;
        while (true)
        {
            pthread_mutex_lock(&_mutex);
                if (_task_list.empty())
                {
                        recved_info = 0;
                }
                else
                {
                        recved_info = _task_list.front();
                        _task_list.pop_front();
                }
            pthread_mutex_unlock(&_mutex);

                if (recved_info == 0)
                {
                        int f = usleep(1);
            continue;
        }
    }
}

在5.3上运行时,您甚至找不到最上面的进程,CPU使用率约为0%.但是在cent os 6.3上,在4核cpu上有6个线程,大约占20%.

While running on the 5.3, you can't even find the process on top, cpu usage is around 0%. But on cent os 6.3, it's about 20% with 6 threads on a 4 cores cpu.

所以我用 time stace 检查a.out,结果是这样的:

So I check the a.out with time and stace , the results are about that:

在5.3上:

real    0m14.003s
user    0m0.001s
sys     0m0.001s

在6.3上:

real    0m14.002s
user    0m1.484s
sys  0m1.160s

strace:

在5.3上:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 91.71    0.002997           0     14965           nanosleep
  8.29    0.000271         271         1           execve
  0.00    0.000000           0         5           read
  0.00    0.000000           0        10         4 open
  0.00    0.000000           0         6           close
  0.00    0.000000           0         4         4 stat
  0.00    0.000000           0         6           fstat
  0.00    0.000000           0        22           mmap
  0.00    0.000000           0        13           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         3           rt_sigprocmask
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         3           clone
  0.00    0.000000           0         1           uname
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0        38         4 futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         4           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.003268                 15092        13 total

在6.3:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.99    1.372813          36     38219           nanosleep
  0.01    0.000104           0       409        43 futex
  0.00    0.000000           0         5           read
  0.00    0.000000           0         6           open
  0.00    0.000000           0         6           close
  0.00    0.000000           0         6           fstat
  0.00    0.000000           0        22           mmap
  0.00    0.000000           0        15           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         3           rt_sigprocmask
  0.00    0.000000           0         7         7 access
  0.00    0.000000           0         3           clone
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         4           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    1.372917                 38716        50 total

时间和strace结果测试不同,因此数据略有不同.但是我认为它可以显示一些东西.

The time and the strace results are not the same test, so data is a little different. But I think it can show something.

我检查内核配置CONFIG_HIGH_RES_TIMERS,CONFIG_HPET和CONFIG_HZ:

I check the kernel config CONFIG_HIGH_RES_TIMERS, CONFIG_HPET and CONFIG_HZ:

在5.3上:

$ cat /boot/config-`uname -r` |grep CONFIG_HIGH_RES_TIMERS
$ cat /boot/config-`uname -r` |grep CONFIG_HPET
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
# CONFIG_HPET_MMAP is not set
$ cat /boot/config-`uname -r` |grep CONFIG_HZ
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000

在6.3上:

$ cat /boot/config-`uname -r` |grep CONFIG_HIGH_RES_TIMERS
CONFIG_HIGH_RES_TIMERS=y
$ cat /boot/config-`uname -r` |grep CONFIG_HPET
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
$ cat /boot/config-`uname -r` |grep CONFIG_HZ
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000

事实上,我还尝试了在ARM和xubuntu13.04-amd64-desktop上的arch上的代码,与cent os 6.3相同.

In fact, I also try the code on arch on ARM and xubuntu13.04-amd64-desktop, the same as the cent os 6.3.

那么我该怎么办才能找出导致CPU使用率不同的原因?

So what can I do to figure out the reason of the different CPU usages?

它与内核配置有关吗?

推荐答案

您是正确的,它与内核配置有关. usleep(1)将尝试睡眠一微秒.在使用高分辨率计时器之前,您不可能睡眠少于一秒钟(在您的情况下,HZ = 1000,所以1秒钟== 1毫秒).

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).

在没有这些高分辨率计时器的CentOS 5.3上,您将在1毫秒至2毫秒之间睡眠[1].在具有这些计时器的CentOS 6.3上,您的睡眠时间接近一微秒.这就是为什么您在此平台上使用更多CPU的原因:您只是在轮询任务列表500-1000次以上.

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.

如果将代码更改为usleep(1000),则CentOS 5.3的行为将相同. CentOS 6.3的CPU时间将减少,并且与CentOS 5.3上运行的程序处于同一水平

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

Linux手册对此进行了全面讨论:运行man 7 time.

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.

此外,您的主系统应该真正加入线程,而不是只睡14秒.

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

[1]有一个例外.如果您的应用程序是在实时调度策略(SCHED_FIFO或SCHED_RR)下运行的,则它将忙于等待而不是休眠以接近正确的数量.但是默认情况下,您需要root权限

[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

这篇关于Cent OS 6.3上的usleep的CPU高使用率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆