Chinaunix

标题: 各位大侠进来看看 同样程序suse和centos 占有cpu不一样 [打印本页]

作者: chestnut king    时间: 2013-01-16 18:07
标题: 各位大侠进来看看 同样程序suse和centos 占有cpu不一样
同样一个程序在suse 下 cpu 几乎是0  ,但是在centos 下,cpu 5%左右 有办法解决吗???
#include <stdio.h>
#include <unistd.h>
int main()
{
           while(1)
           {
                      usleep(1);
           }
           return 1;
}
作者: hellioncu    时间: 2013-01-16 20:14
这解决了有什么意义呢
作者: linux_c_py_php    时间: 2013-01-16 20:47
统一一下gcc版本。
作者: chestnut king    时间: 2013-01-17 11:09
客户不满意,说什么都没跑,cpu就占了10%
作者: hellioncu    时间: 2013-01-17 11:29
要么sleep时间长点,要么改用等待信号
作者: zylthinking    时间: 2013-01-17 12:14
这个其实我很不明白。。。。。。。。。。。
作者: csumck    时间: 2013-01-17 12:42
top一下,看看是具体是哪种占用,是usr 还是sys 还是wait
作者: fender0107401    时间: 2013-01-17 13:37
gcc优化程度不一样或者是版本不一样导致的优化方法不一样。
作者: fender0107401    时间: 2013-01-17 13:37
换高版本的gcc。
作者: shan_ghost    时间: 2013-01-17 13:55
sleep并不保证让出CPU,也可以是忙等,只是早期实现都让出CPU了,新版gcc还是内核不再这么做。前些天有过报道的。
作者: zylthinking    时间: 2013-01-17 14:12
shan_ghost 发表于 2013-01-17 13:55
sleep并不保证让出CPU,也可以是忙等,只是早期实现都让出CPU了,新版gcc还是内核不再这么做。前些天有过报 ...


但这样为什么 CPU 不是 100%, 而仅仅 5%?
作者: shan_ghost    时间: 2013-01-17 14:17
zylthinking 发表于 2013-01-17 14:12
但这样为什么 CPU 不是 100%, 而仅仅 5%?


这个就不清楚了,没深入研究过。反正是不能再用sleep代替等待信号就对了……
作者: zylthinking    时间: 2013-01-17 14:29
shan_ghost 发表于 2013-01-17 14:17
这个就不清楚了,没深入研究过。反正是不能再用sleep代替等待信号就对了……


我觉得你这句话就错了, 要是 sleep 基于秒级的还用忙等, 那做出这个决定的人就应该找块豆腐一头撞死;
事实上, 据我所直, 2.4 内核就已经有这个措施, 当睡眠时间过短, 则会采用忙等形式而不是睡眠; 这个绝对不是什么新东西; 新代码中, 倒是有可能将什么是睡眠过短这个定义给改点, 但若说 sleep(1) 会忙等, 我觉得这是个无脑袋的想法
作者: shan_ghost    时间: 2013-01-17 14:36
zylthinking 发表于 2013-01-17 14:29
我觉得你这句话就错了, 要是 sleep 基于秒级的还用忙等, 那做出这个决定的人就应该找块豆腐一头撞死; ...


这点你是对的。

另,注意楼主用的是usleep(1)。
作者: zylthinking    时间: 2013-01-17 14:37
shan_ghost 发表于 2013-01-17 14:36
这点你是对的。

另,注意楼主用的是usleep(1)。


反正是不能再用sleep代替等待信号就对了
作者: shan_ghost    时间: 2013-01-17 14:57
本帖最后由 shan_ghost 于 2013-01-17 15:02 编辑
zylthinking 发表于 2013-01-17 14:37
反正是不能再用sleep代替等待信号就对了


查到资料了。的确是不能再用sleep/usleep系列函数代替等待信号了:

http://www.360doc.com/content/11/1201/09/1317564_168809827.shtml

大概是说,系统把定时器分组维护,越快到期的定时器组会被越频繁的扫描。

比如,如果一个组的定时器要1小时后到期,那么这个组每5分钟或更长时间关注一次就够了;而如果一个组的定时器1分钟后就可能到期,那么可能至少1分钟就得去检查一次。

linux内核把定时器按时间远近分成4个组,给它们不同的关注频率。当低优先级的一个定时器即将到期时,linux会自动把它转到高优先组里。


这样,对sleep(3600s),它可能一开始在第4组(随便写的),50分钟后被移到第3组,9分钟后到第2组,50秒后到第一组。



但,因为性能原因,linux本身能支持的最小时间粒度是有限的,也就是说,哪怕是第一组,它也难以得到1us乃至更高的精度;此时额外的精度就只能通过忙等提供了。


实现上,就是第一组的定时器到期后,相关进/线程被唤起,然后由线程内的忙等来得到更精确的定时效果。

如此一来,sleep(1)当然还会出让CPU并等待信号;但,为了得到精确的sleep(1)效果,最后常常多余出来的一点点“时间尾巴”就只能忙等。
于是,sleep(1)/usleep(1)就必须多消耗一点点CPU,这就是5%CPU占用率的由来。

作者: zylthinking    时间: 2013-01-17 15:11
shan_ghost 发表于 2013-01-17 14:57
查到资料了。的确是不能再用sleep/usleep系列函数代替等待信号了:

http://www.360doc.com/content/ ...


我真不知说什么了, 我看了一下, 通篇是介绍 2.4 内核的 timer 机制; 我想这个我还有点了解, 却不知你的以上的论断哪里来的;
timer 之所以如此实现, 完全是为了性能做的一个算法, 具体算法不说, 但却无法得到你所谓的 sleep(1) 不能用来等信号之类的事情的结论;

timer 到时之后, 调用的是 bottom half, 这个链表是各个驱动挂进去的, 作为一种给驱动程序一个延迟执行之类的服务; 而且是一到时间, 立刻执行, 哪里还有什么 timer 到时之后, 之后还有忙等逻辑, 你到底是没看懂了还是想用来蒙我呢
作者: shan_ghost    时间: 2013-01-17 15:15
本帖最后由 shan_ghost 于 2013-01-17 15:15 编辑
zylthinking 发表于 2013-01-17 15:11
我真不知说什么了, 我看了一下, 通篇是介绍 2.4 内核的 timer 机制; 我想这个我还有点了解, 却不知 ...


呵呵,这个5%左右的数据以及相关机制是之前那个报道提到过的。我当时没认真看,大致了解下就过去了。所以遇到这个问题的时候,一时就想不起了。

现在有了这个文档,有了它关于2.4内核timer实现机制之类知识一引导,那篇文章的内容自然就回想起来了。
作者: shan_ghost    时间: 2013-01-17 15:19
记得好像是linus或者那几个人说的,也可能是偶自动综合了他们的言论:大意就是2.4的内核能提供更精确的时钟,但代价是过去依赖sleep让出控制权的程序就要多占用百分之几的CPU。但sleep本来就不是为出让CPU而设计的,不按文档使用的后果只能由使用者自己承担。
作者: shan_ghost    时间: 2013-01-17 15:22
…………但是那篇文章死活就是找不到了……
作者: zylthinking    时间: 2013-01-17 16:13
shan_ghost 发表于 2013-01-17 15:19
记得好像是linus或者那几个人说的,也可能是偶自动综合了他们的言论:大意就是2.4的内核能提供更精确的时钟 ...


在没有看到原文前, 我也怀疑你这些话; 我很怀疑你又拿什么所谓资料做噱头然后蒙我;
就原理来讲, timer list 执行时位于中断下半部, 那么必然是随机发生于各个进程上下文内, 不会单单看着调用了 sleep 的进程好欺负; timer list  并不会因为调用了 sleep 而存在, 没有了 sleep 就不存在了; CPU 的消耗不会有区别;
最重要的是, 无论如何, 得不出你所谓不应该调用 sleep 来等待什么信号的结论来, 或者说 sleep 不是为让出 cpu 来设计的, 靠, 那他是为什么来设计的?

作者: shan_ghost    时间: 2013-01-17 16:32
靠,抓源码,看来是我记错了:

首先。2.4内核,小于2ms、且current->policy != SCHED_OTHER会忙等,而且不会出现任务切换:
(current->policy != SCHED_OTHER的意思是检查当前进程是否实时进程,只有是实时进程才会忙等,否则仍然发生任务切换。)

http://students.mimuw.edu.pl/SO/Linux/Kod/kernel/sched.c.html

asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
{
        int error;
        struct timespec t;
        unsigned long expire;

        error = verify_area(VERIFY_READ, rqtp, sizeof(struct timespec));
        if (error)
                return error;
        memcpy_fromfs(&t, rqtp, sizeof(struct timespec));
        if (rmtp) {
                error = verify_area(VERIFY_WRITE, rmtp,
                                    sizeof(struct timespec));
                if (error)
                        return error;
        }

        if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
                return -EINVAL;

        if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
            current->policy != SCHED_OTHER) {
                /*
                 * Short delay requests up to 2 ms will be handled with
                 * high precision by a busy wait for all real-time processes.
                 */
                udelay((t.tv_nsec + 999) / 1000);
                return 0;
        }

        expire = timespectojiffies(&t) + (t.tv_sec || t.tv_nsec) + jiffies;
        current->timeout = expire;
        current->state = TASK_INTERRUPTIBLE;
        schedule();

        if (expire > jiffies) {
                if (rmtp) {
                        jiffiestotimespec(expire - jiffies -
                                          (expire > jiffies + 1), &t);
                        memcpy_tofs(rmtp, &t, sizeof(struct timespec));
                }
                return -EINTR;
        }

        return 0;
}

libc的sleep/usleep实现,其实就是直接调用了sys_nanosleep,所以分析sys_nanosleep就行了:
http://cristi.indefero.net/p/uCl ... libc/unistd/sleep.c
http://cristi.indefero.net/p/uCl ... ibc/unistd/usleep.c


总之,看来我之前看到那篇文章是错的。2.4的改变,除了更好的支持了实时程序外,其实并不会造成任何可见影响。
作者: shan_ghost    时间: 2013-01-17 16:33
zylthinking 发表于 2013-01-17 16:13
在没有看到原文前, 我也怀疑你这些话; 我很怀疑你又拿什么所谓资料做噱头然后蒙我;
就原理来讲, t ...


呵呵,是我错了。当时看到那篇文章时没认真鉴别,学到错误的东西了……
作者: mordorwww    时间: 2016-06-26 16:01
本帖最后由 mordorwww 于 2016-06-26 16:02 编辑

真sleep 1us的话CPU占用很高吧,你想1us做一次进程调度和切换,1ms做一千次
而如果忙等的话,你这进程就一死循环, CPU占用100%了吧
见过脚本里睡眠太频繁CPU占用就很高,百分之几十(600Mhz arm)
作者: windoze    时间: 2016-06-27 02:10
回复 24# mordorwww

楼上考的一手好古。
正纳闷这个HighRes Timer的锅怎么又冒出来了,仔细一看原来是3年前的帖子……
作者: mordorwww    时间: 2016-06-27 10:10
windoze 发表于 2016-06-27 02:10
回复 24# mordorwww

楼上考的一手好古。



回帖里提到的等待信号 是什么,百度 谷歌都没搜到这个概念
而且我验证在 CentOS release 6.5 (Final) 版本 里确实如楼主所说。
每1us醒来一次,这个不会让CPU占用很高么

感觉这个应该移到内核版
作者: windoze    时间: 2016-06-27 10:19
回复 26# mordorwww

这是HiRes Timer惹的祸,之前计时用的是jiffy,这个东西没成本但是不准,后来改成HiRes Timer了,这个东西很准但是有点贵。
作者: mordorwww    时间: 2016-06-27 11:13
windoze 发表于 2016-06-27 10:19
回复 26# mordorwww

这是HiRes Timer惹的祸,之前计时用的是jiffy,这个东西没成本但是不准,后来改成H ...


1s 钟做 1百万次 sleep操作,i3  CPU占用才5%(1Ghz arm占用 18%),那说明现在CPU很强大嘛,HiRes Timer也不算太贵嘛



1Ghz arm
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                          
3824 root      20   0    1192    236    184 S 19.3  0.0   0:35.32 r


3.4Ghz i3
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                
28383 root      20   0  3920  340  276 S  4.3  0.0   2:56.14 r                                                                                                                                      
8056 root      20   0  3920  344  276 S  4.0  0.0   0:00.32 r
作者: fender0107401    时间: 2016-06-27 13:21
学习学习。
作者: cokeboL    时间: 2016-06-27 13:45
挖的一手好坟
作者: Sevk    时间: 2016-06-27 16:16
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2