Cent OS 6.3上的usleep的CPU高使用率 [英] CPU high usage of the usleep on Cent OS 6.3
问题描述
我在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屋!