前段时间调试一个程序的性能,发现当系统的负载增加到某一个临界值的时候,系统的CPU利用率会急剧上升,而在这个邻接点往下,系统的CPU利用率都是出奇的轻,百思不得其解。
开始以为是某个东西具有非线性的负载CPU利用率,一路从软件到硬件排查了一遍后,逐个都洗清了嫌疑。后来,一个数据让我有点儿豁然开朗的感觉,那就是n个核心就有n倍单核心的throughput,这个数据显示系统的scalability还是相当不错的。联系到程序的一些实现方式,并研读了Linux内核统计CPU利用率的代码后,我的猜测得到了印证:Linux下的CPU利用率统计对我们这个系统实现来说,不准确。
不太相信,我是第一个碰到这个问题的人,随即google了一番,原来内核代码中的一个文档
Documentation/cpu-load.txt早在2007年就发现并记下了这个问题。鉴于那篇文章比较清楚的描述了这种误差出现的原因,我这里就不再赘述了。
那么都什么情况会导致Linux统计的CPU利用率和实际情况偏差很大呢?
所有依赖于Linux的滴答定时器(tick timer)唤醒的任务,如内核里面的动态定时器(dynamic timer),用户空间定时执行的任务等。
现今的内核截至到2.6.29都没有针对这个问题进行修正,我想以后也不太可能会为了这一类负载而大动干戈,那么我们如何回避这个问题呢?
- 去除对tick timer的依赖,如果可以的话。
- 测试采用benchmark的形式,即在cpu全负荷情况下测试其他数据,间接反应程序效率。
如果以上提到的两种方法都不适合,可以尝试改变CPU利用率的计算方法。Linux现在有目录/sys/devices/system/cpu/cpuidle和/sys/devices/system/cpu/cpu[0..]/cpuidle/state[0..]/,里面的time分别对应着系统处于某个idle state的时间,将其累加再除以系统的uptime,再用1减去,就得到CPU利用率,当然,这个时候你别指望能得到system time等其他信息了,不过,毕竟寥胜于无!
参考文档:
- Documentation/cpuidle
阅读(3110) | 评论(0) | 转发(0) |