強(qiáng)悍!Linux啟動時間的極限優(yōu)化
在上次完成嵌入式應(yīng)用的Linux裁減后,Linux的啟動時間仍需要 7s 左右,雖然勉強(qiáng)可以接受,但仍然沒有達(dá)到我個人所追求的目標(biāo)——2s 以內(nèi)。況且,在實(shí)際的商用環(huán)境中,設(shè)備可靠性的要求可是“5個9”(99.999%,即OOS時間低于5分鐘/年),這就意味著每減少一秒鐘Linux啟動(設(shè)備復(fù)位)時間,對可靠性都是一個明顯的提升。
言歸正傳,如何著手對Linux的啟動時間進(jìn)行優(yōu)化呢?
CELF(The Consumer Electronics Linux Forum)論壇為我們指引了一個方向。
(1)首先是對Linux啟動過程的跟蹤和分析,生成詳細(xì)的啟動時間報告。
較為簡單可行的方式是通過PrintkTime功能為啟動過程的所有內(nèi)核信息增加時間戳,便于匯總分析。PrintkTime最早為CELF所提供的一個內(nèi)核補(bǔ)丁,在后來的Kernel 2.6.11版本中正式納入標(biāo)準(zhǔn)內(nèi)核。所以大家可能在新版本的內(nèi)核中直接啟用該功能。如果你的Linux內(nèi)核因?yàn)槟承┰虿荒芨聻?.6.11之后的版本,那么可以參考CELF提供的方法修改或直接下載它們提供的補(bǔ)丁:http://tree.celinuxforum.org/CelfPubWiki/PrintkTimes
開啟PrintkTime功能的方法很簡單,只需在內(nèi)核啟動參數(shù)中增加“time”即可。當(dāng)然,你也可以選擇在編譯內(nèi)核時直接指定“Kernel hacking”中的“Show timing information on printks”來強(qiáng)制每次啟動均為內(nèi)核信息增加時間戳。這一種方式還有另一個好處:你可以得到內(nèi)核在解析啟動參數(shù)前所有信息的時間。因此,我選擇后一種方式。
當(dāng)完成上述配置后,重新啟動Linux,然后通過以下命令將內(nèi)核啟動信息輸出到文件:
dmesg -s 131072 > ktime
然后利用一個腳本“show_delta”(位于Linux源碼的scripts文件夾下)將上述輸出的文件轉(zhuǎn)換為時間增量顯示格式:
/usr/src/linux-x.xx.xx/scripts/show_delta ktime > dtime
這樣,你就得到了一份關(guān)于Linux啟動時間消耗的詳細(xì)報告。
(2)然后,我們就來通過這份報告,找出啟動中相對耗時的過程。
必須明確一點(diǎn):報告中的時間增量和內(nèi)核信息之間沒有必然的對應(yīng)關(guān)系,真正的時間消耗必須從內(nèi)核源碼入手分析。
這一點(diǎn)對于稍微熟悉編程的朋友來說都不難理解,因?yàn)闀r間增量只是兩次調(diào)用printk之間的時間差值。通常來說,內(nèi)核啟動過程中在完成一些耗時的任務(wù),如創(chuàng)建hash索引、probe硬件設(shè)備等操作后會通過printk將結(jié)果打印出來,這種情況下,時間增量往往反映的是信息對應(yīng)過程的耗時;但有些時候,內(nèi)核是在調(diào)用printk輸出信息后才開始相應(yīng)的過程,那么報告中內(nèi)核信息相應(yīng)過程的時間消耗對應(yīng)的是其下一行的時間增量;還有一些時候,時間消耗在了兩次內(nèi)核信息輸出之間的某個不確定的時段,這樣時間增量可能就完全無法通過內(nèi)核信息反應(yīng)出來了。
所以,為了準(zhǔn)確判斷真正的時間消耗,我們需要結(jié)合內(nèi)核源碼進(jìn)行分析。必要的時候,例如上述第三種情形下,還得自己在源碼中插入printk打印,以進(jìn)一步確定實(shí)際的時間消耗過程。
以下是我上次裁減后Linux內(nèi)核的啟動分析:
內(nèi)核啟動總時間: 6.188s
關(guān)鍵的耗時部分:
1) 0.652s - Timer,IRQ,Cache,Mem Pages等核心部分的初始化
2) 0.611s - 內(nèi)核與RTC時鐘同步
3) 0.328s - 計(jì)算Calibrating Delay(4個CPU核心的總消耗)
4) 0.144s - 校準(zhǔn)APIC時鐘
5) 0.312s - 校準(zhǔn)Migration Cost
6) 3.520s - Intel E1000網(wǎng)卡初始化
下面,將針對上述各部分進(jìn)行逐一分析和化解。
(3)接下來,進(jìn)行具體的分項(xiàng)優(yōu)化。
CELF已經(jīng)提出了一整套針對消費(fèi)類電子產(chǎn)品所使用的嵌入式Linux的啟動優(yōu)化方案,但是由于面向不同應(yīng)用,所以我們只能部分借鑒他們的經(jīng)驗(yàn),針對自己面對的問題作出具體的分析和嘗試。
內(nèi)核關(guān)鍵部分(Timer、IRQ、Cache、Mem Pages……)的初始化目前暫時沒有比較可靠和可行的優(yōu)化方案,所以暫不考慮。
對于上面分析結(jié)果中的 2、3 兩項(xiàng),CELF已有專項(xiàng)的優(yōu)化方案:“RTCNoSync”和“PresetLPJ”。
前者通過屏蔽啟動過程中所進(jìn)行的RTC時鐘同步或者將這一過程放到啟動后進(jìn)行(視具體應(yīng)用對時鐘精度的需求而定),實(shí)現(xiàn)起來比較容易,但需要為內(nèi)核打補(bǔ)丁。似乎CELF目前的工作僅僅是去掉了該過程,而沒有實(shí)現(xiàn)所提到的“延后”處理RTC時鐘的同步。考慮到這個原因,我的方案中暫時沒有引入這一優(yōu)化(畢竟它所帶來的時間漂移已經(jīng)達(dá)到了“秒”級),繼續(xù)關(guān)注中。
后者是通過在啟動參數(shù)中強(qiáng)制指定LPJ值而跳過實(shí)際的計(jì)算過程,這是基于LPJ值在硬件條件不變的情況下不會變化的考慮。所以在正常啟動后記錄下內(nèi)核信息中的“Calibrating Delay”數(shù)值后就可以在啟動參數(shù)中以下面的形式強(qiáng)制指定LPJ值了:
lpj=9600700
上面分析結(jié)果
新文章:
- CentOS7下圖形配置網(wǎng)絡(luò)的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動項(xiàng)
- CentOS單網(wǎng)卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗(yàn)證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網(wǎng)打印機(jī)IP講解
- CentOS7使用hostapd實(shí)現(xiàn)無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網(wǎng)絡(luò)重啟出錯
- 解決Centos7雙系統(tǒng)后丟失windows啟動項(xiàng)
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認(rèn)iptable規(guī)則詳解