您的位置 首页 新能源

Linux发动时刻的极限优化

在上次完成嵌入式应用的Linux裁减后,Linux的启动时间仍需要 7s 左右,虽然勉强可以接受,但仍然没有达到我个人所追求的目标——2s 以内。况且

在前次完结嵌入式运用的Linux削减后,Linux的发动时刻仍需求 7s 左右,尽管牵强能够承受,但仍然没有到达我个人所寻求的方针——2s 以内。何况,在实践的商用环境中,设备牢靠性的要求可是“5个9”(99.999%,即OOS时刻低于5分钟/年),这就意味着每削减一秒钟Linux发动(设备复位)时刻,对牢靠性都是一个显着的提高。

言归正传,怎么着手对Linux的发动时刻进行优化呢?

CELF(The Consumer Electronics Linux Forum)论坛为咱们指引了一个方向。

(1)首先是对Linux发动进程的盯梢和剖析,生成详细的发动时刻陈述。

较为简略可行的办法是经过PrintkTime功用为发动进程的一切内核信息添加时刻戳,便于汇总剖析。PrintkTime最早为CELF所供给的一个内核补丁,在后来的Kernel 2.6.11版别中正式归入规范内核。所以咱们或许在新版别的内核中直接启用该功用。假如你的Linux内核因为某些原因不能更新为2.6.11之后的版别,那么能够参阅CELF供给的办法修正或直接下载它们供给的补丁:linuxforum.org/CelfPubWiki>http://tree.celinuxforum.org/CelfPubWiki /PrintkTimes

敞开PrintkTime功用的办法很简略,只需在内核发动参数中添加“time”即可。当然,你也能够挑选在编译内核时直接指定“Kernel hacking”中的“Show timing information on printks”来强制每次发动均为内核信息添加时刻戳。这一种办法还有另一个优点:你能够得到内核在解析发动参数前一切信息的时刻。因而,我挑选后一种办法。

当完结上述装备后,重新发动Linux,然后经过以下指令将内核发动信息输出到文件:

dmesg -s 131072 >ktime

然后运用一个脚本“show_delta”(坐落Linux源码的scripts文件夹下)将上述输出的文件转化为时刻增量显现格局:

/usr/src/linux-x.xx.xx/scripts/show_delta ktime >dtime

这样,你就得到了一份关于Linux发动时刻耗费的详细陈述。

(2)然后,咱们就来经过这份陈述,找出发动中相对耗时的进程。

有必要清晰一点:陈述中的时刻增量和内核信息之间没有必定的对应联系,真实的时刻耗费有必要从内核源码下手剖析。

这一点关于略微了解编程的朋友来说都不难了解,因为时刻增量仅仅两次调用printk之间的时刻差值。一般来说,内核发动进程中在完结一些耗时的使命,如创立hash索引、probe硬件设备等操作后会经过printk将成果打印出来,这种情况下,时刻增量往往反映的是信息对应进程的耗时;但有些时分,内核是在调用printk输出信息后才开端相应的进程,那么陈述中内核信息相应进程的时刻耗费对应的是其下一行的时刻增量;还有一些时分,时刻耗费在了两次内核信息输出之间的某个不确认的时段,这样时刻增量或许就彻底无法经过内核信息反应出来了。

所以,为了精确判别真实的时刻耗费,咱们需求结合内核源码进行剖析。必要的时分,例如上述第三种景象下,还得自己在源码中刺进printk打印,以进一步确认实践的时刻耗费进程。

以下是我前次削减后Linux内核的发动剖析:

内核发动总时刻: 6.188s

要害的耗时部分:

1) 0.652s – Timer,IRQ,Cache,Mem Pages等中心部分的初始化

2) 0.611s – 内核与RTC时钟同步

3) 0.328s – 核算Calibrating Delay(4个CPU中心的总耗费)

4) 0.144s – 校准APIC时钟

5) 0.312s – 校准Migration Cost

6) 3.520s – Intel E1000网卡初始化

下面,将针对上述各部分进行逐个剖析和化解。

(3)接下来,进行详细的分项优化。

CELF现已提出了一整套针对消费类电子产品所运用的嵌入式Linux的发动优化计划,可是因为面向不同运用,所以咱们只能部分学习他们的经历,针对自己面临的问题作出详细的剖析和测验。

内核要害部分(Timer、IRQ、Cache、Mem Pages……)的初始化现在暂时没有比较牢靠和可行的优化计划,所以暂不考虑。

关于上面剖析成果中的 2、3 两项,CELF已有专项的优化计划:“RTCNoSync”和“PresetLPJ”。

前者经过屏蔽发动进程中所进行的RTC时钟同步或许将这一进程放到发动后进行(视详细运用对时钟精度的需求而定),完成起来比较简单,但需求为内核打补丁。好像CELF现在的作业仅仅是去掉了该进程,而没有完成所说到的“拖延”处理RTC时钟的同步。考虑到这个原因,我的计划中暂时没有引进这一优化(究竟它所带来的时刻漂移现已到达了“秒”级),持续重视中。

后者是经过在发动参数中强制指定LPJ值而越过实践的核算进程,这是根据LPJ值在硬件条件不变的情况下不会改变的考虑。所以在正常发动跋文录下内核信息中的“Calibrating Delay”数值后就能够在发动参数中以下面的办法强制指定LPJ值了:

lpj=9600700

上面剖析成果中的 4、5 两项都是SMP初始化的一部分,因而不在CELF研讨的领域(或许将来会有选用多核的MP4呈现?……),只能自给自足了。研讨了一下SMP的初始化代码,发现“Migration Cost”其实也能够像“Calibrating Delay”选用预置的办法越过校准时刻。办法相似,终究在内核发动参数中添加:

migration_cost=4000,4000

而Intel的网卡驱动初始化优化起来就比较麻烦了,尽管也是开源,但读硬件驱动彻底不比读一般的C代码,何况建立在如此浅薄了解基础上的“优化”修正也真实难保万全。根据牢靠性的考虑,我终究在两次测验均告失败后抛弃了这一条路。那么,换一个思维视点,能够学习CELF在“ParallelRCScripts”计划中的“并行初始化”思维,将网卡驱动独立编译为模块,放在初始化脚本中与其它模块和运用同步加载,然后消除Probe堵塞对发动时刻的影响。考虑到运用初始化也或许运用到网络,而在咱们的实践硬件环境中,只要eth0是供运用运用的,因而需求将第一个网口初始化的0.3s时刻核算在内。

除了在我的计划中所遇到的上述各优化点,CELF还提出了一些你或许会感兴趣的有特定针对性的专项优化,如:

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/xinnengyuan/297517.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部