位置:51电子网 » 技术资料 » 其它综合

Linux系统启动时间的极限优化

发布时间:2008/5/28 0:00:00 访问次数:487

  (1)首先是对linux启动过程的跟踪和分析,生成详细的启动时间报告。

  较为简单可行的方式是通过printktime功能为启动过程的所有内核信息增加时间戳,便于汇总分析。printktime最早为celf所提供的一个内核补丁,在后来的kernel2.6.11版本中正式纳入标准内核。所以大家可能在新版本的内核中直接启用该功能。如果你的linux内核因为某些原因不能更新为2.6.11之后的版本,那么可以参考celf提供的方法修改或直接下载它们提供的补丁:http://tree.celinuxforum.org/celfpubwiki/printktimes

  开启printktime功能的方法很简单,只需在内核启动参数中增加“time”即可。当然,你也可以选择在编译内核时直接指定“kernelhacking”中的“showtiminginformationonprintks”来强制每次启动均为内核信息增加时间戳。这一种方式还有另一个好处:你可以得到内核在解析启动参数前所有信息的时间。因此,我选择后一种方式。

  当完成上述配置后,重新启动linux,然后通过以下命令将内核启动信息输出到文件:

  dmesg-s131072>ktime

  然后利用一个脚本“show_delta”(位于linux源码的scripts文件夹下)将上述输出的文件转换为时间增量显示格式:

  /usr/src/linux-x.xx.xx/scripts/show_deltaktime>dtime

  这样,你就得到了一份关于linux启动时间消耗的详细报告。

  (2)然后,我们就来通过这份报告,找出启动中相对耗时的过程。

  必须明确一点:报告中的时间增量和内核信息之间没有必然的对应关系,真正的时间消耗必须从内核源码入手分析。

  这一点对于稍微熟悉编程的朋友来说都不难理解,因为时间增量只是两次调用printk之间的时间差值。通常来说,内核启动过程中在完成一些耗时的任务,如创建hash索引、probe硬件设备等操作后会通过printk将结果打印出来,这种情况下,时间增量往往反映的是信息对应过程的耗时;但有些时候,内核是在调用printk输出信息后才开始相应的过程,那么报告中内核信息相应过程的时间消耗对应的是其下一行的时间增量;还有一些时候,时间消耗在了两次内核信息输出之间的某个不确定的时段,这样时间增量可能就完全无法通过内核信息反应出来了。

  所以,为了准确判断真正的时间消耗,我们需要结合内核源码进行分析。必要的时候,例如上述第三种情形下,还得自己在源码中插入printk打印,以进一步确定实际的时间消耗过程。

  以下是我上次裁减后linux内核的启动分析:

  内核启动总时间:6.188s

  关键的耗时部分:

  1)0.652s-timer,irq,cache,mempages等核心部分的初始化

  2)0.611s-内核与rtc时钟同步

  3)0.328s-计算calibratingdelay(4个cpu核心的总消耗)

  4)0.144s-校准apic时钟

  5)0.312s-校准migrationcost

  6)3.520s-intele1000网卡初始化

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

  (3)接下来,进行具体的分项优化。

  celf已经提出了一整套针对消费类电子产品所使用的嵌入式linux的启动优化方案,但是由于面向不同应用,所以我们只能部分借鉴他们的经验,针对自己面对的问题作出具体的分析和尝试。

  内核关键部分(timer、irq、cache、mempages……)的初始化目前暂时没有比较可靠和可行的优化方案,所以暂不考虑。

  对于上面分析结果中的2、3两项,celf已有专项的优化方案:“rtcnosync”和“presetlpj”。

  前者通过屏蔽启动过程中所进行的rtc时钟同步或者将这一过程放到启动后进行(视具体应用对时钟精度的需求而定),实现起来比较容易,但需要为内核打补丁。似乎celf目前的工作仅仅是去掉了该过程,而没有实现所提到的“延后”处理rtc时钟的同步。考虑到这个原因,我的方案中暂时没有引入这一优化(毕竟它所带来的时间漂移已经达到了“秒”级),继续关注中。

  后者是通过在启动参数中强制指定lpj值而跳过实际的计算过程,这是基于lpj值在硬件条件不变的情况下不会变化的考虑。所以在正常启动后记录下内核信息中的“calibratingdelay”数值后就可以在启动参数中以下面的形式强制指定lpj值了:


  lpj=9600700

  上面分析结果中的4、5两项都是smp初始化的一部分,因此不在celf研究的范畴(或许将来会有采用多核的mp4出现?……),只能自力更生了。研究了一下smp的初始化代码,发现“migrationcost”其实也可以像“calibratingdelay”采用预置的方式跳过校准时间。方法类似,最后在内核启动参数中增加:

  migration_cost=4000,4000

  而intel的网卡驱动初始化优化起来就比较麻烦了,虽然也是开源,但读硬件驱动完全不比读一般的c代码,况且建立在如此肤浅理解基础上的“优化”修改也实在难保万

  (1)首先是对linux启动过程的跟踪和分析,生成详细的启动时间报告。

  较为简单可行的方式是通过printktime功能为启动过程的所有内核信息增加时间戳,便于汇总分析。printktime最早为celf所提供的一个内核补丁,在后来的kernel2.6.11版本中正式纳入标准内核。所以大家可能在新版本的内核中直接启用该功能。如果你的linux内核因为某些原因不能更新为2.6.11之后的版本,那么可以参考celf提供的方法修改或直接下载它们提供的补丁:http://tree.celinuxforum.org/celfpubwiki/printktimes

  开启printktime功能的方法很简单,只需在内核启动参数中增加“time”即可。当然,你也可以选择在编译内核时直接指定“kernelhacking”中的“showtiminginformationonprintks”来强制每次启动均为内核信息增加时间戳。这一种方式还有另一个好处:你可以得到内核在解析启动参数前所有信息的时间。因此,我选择后一种方式。

  当完成上述配置后,重新启动linux,然后通过以下命令将内核启动信息输出到文件:

  dmesg-s131072>ktime

  然后利用一个脚本“show_delta”(位于linux源码的scripts文件夹下)将上述输出的文件转换为时间增量显示格式:

  /usr/src/linux-x.xx.xx/scripts/show_deltaktime>dtime

  这样,你就得到了一份关于linux启动时间消耗的详细报告。

  (2)然后,我们就来通过这份报告,找出启动中相对耗时的过程。

  必须明确一点:报告中的时间增量和内核信息之间没有必然的对应关系,真正的时间消耗必须从内核源码入手分析。

  这一点对于稍微熟悉编程的朋友来说都不难理解,因为时间增量只是两次调用printk之间的时间差值。通常来说,内核启动过程中在完成一些耗时的任务,如创建hash索引、probe硬件设备等操作后会通过printk将结果打印出来,这种情况下,时间增量往往反映的是信息对应过程的耗时;但有些时候,内核是在调用printk输出信息后才开始相应的过程,那么报告中内核信息相应过程的时间消耗对应的是其下一行的时间增量;还有一些时候,时间消耗在了两次内核信息输出之间的某个不确定的时段,这样时间增量可能就完全无法通过内核信息反应出来了。

  所以,为了准确判断真正的时间消耗,我们需要结合内核源码进行分析。必要的时候,例如上述第三种情形下,还得自己在源码中插入printk打印,以进一步确定实际的时间消耗过程。

  以下是我上次裁减后linux内核的启动分析:

  内核启动总时间:6.188s

  关键的耗时部分:

  1)0.652s-timer,irq,cache,mempages等核心部分的初始化

  2)0.611s-内核与rtc时钟同步

  3)0.328s-计算calibratingdelay(4个cpu核心的总消耗)

  4)0.144s-校准apic时钟

  5)0.312s-校准migrationcost

  6)3.520s-intele1000网卡初始化

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

  (3)接下来,进行具体的分项优化。

  celf已经提出了一整套针对消费类电子产品所使用的嵌入式linux的启动优化方案,但是由于面向不同应用,所以我们只能部分借鉴他们的经验,针对自己面对的问题作出具体的分析和尝试。

  内核关键部分(timer、irq、cache、mempages……)的初始化目前暂时没有比较可靠和可行的优化方案,所以暂不考虑。

  对于上面分析结果中的2、3两项,celf已有专项的优化方案:“rtcnosync”和“presetlpj”。

  前者通过屏蔽启动过程中所进行的rtc时钟同步或者将这一过程放到启动后进行(视具体应用对时钟精度的需求而定),实现起来比较容易,但需要为内核打补丁。似乎celf目前的工作仅仅是去掉了该过程,而没有实现所提到的“延后”处理rtc时钟的同步。考虑到这个原因,我的方案中暂时没有引入这一优化(毕竟它所带来的时间漂移已经达到了“秒”级),继续关注中。

  后者是通过在启动参数中强制指定lpj值而跳过实际的计算过程,这是基于lpj值在硬件条件不变的情况下不会变化的考虑。所以在正常启动后记录下内核信息中的“calibratingdelay”数值后就可以在启动参数中以下面的形式强制指定lpj值了:


  lpj=9600700

  上面分析结果中的4、5两项都是smp初始化的一部分,因此不在celf研究的范畴(或许将来会有采用多核的mp4出现?……),只能自力更生了。研究了一下smp的初始化代码,发现“migrationcost”其实也可以像“calibratingdelay”采用预置的方式跳过校准时间。方法类似,最后在内核启动参数中增加:

  migration_cost=4000,4000

  而intel的网卡驱动初始化优化起来就比较麻烦了,虽然也是开源,但读硬件驱动完全不比读一般的c代码,况且建立在如此肤浅理解基础上的“优化”修改也实在难保万

相关IC型号

热门点击

 

推荐技术资料

罗盘误差及补偿
    造成罗盘误差的主要因素有传感器误差、其他磁材料干扰等。... [详细]
版权所有:51dzw.COM
深圳服务热线:13692101218  13751165337
粤ICP备09112631号-6(miitbeian.gov.cn)
公网安备44030402000607
深圳市碧威特网络技术有限公司
付款方式


 复制成功!