Linux? 的速度或效率都非常不錯(cuò),只是在一些情況下,這樣的速度還不能滿足需求。我們需要的是在特定的容差范圍內(nèi)確定性地滿足調(diào)度期限的能力。本文將揭示各種實(shí)現(xiàn)實(shí)時(shí) Linux 的可選方案以及它們?nèi)绾螌?shí)現(xiàn)實(shí)時(shí)性 — 從早期的模仿虛擬化解決方案的架構(gòu)到如今標(biāo)準(zhǔn) 2.6 內(nèi)核中可用的選項(xiàng)。
本文探索了一些支持實(shí)時(shí)特性的 Linux 架構(gòu),并探討了實(shí)時(shí)架構(gòu) 的含意是什么。有許多種解決方案賦予 Linux 實(shí)時(shí)能力,本文將對(duì)瘦內(nèi)核(或微內(nèi)核)方法、超微內(nèi)核方法以及資源內(nèi)核(resource-kernel)方法進(jìn)行考查。最后,描述了標(biāo)準(zhǔn) 2.6 內(nèi)核的實(shí)時(shí)功能,并向您示范如何啟用并使用這能。
實(shí)時(shí)的定義及要求
下列實(shí)時(shí) 的定義為探討實(shí)時(shí) Linux 架構(gòu)提供了基礎(chǔ)。定義由 Donal Gillies 在 Realtime Computing FAQ 中提出。
實(shí)時(shí)系統(tǒng)指系統(tǒng)的計(jì)算正確性不僅取決于計(jì)算的邏輯正確性,還取決于產(chǎn)生結(jié)果的時(shí)間。如果未滿足系統(tǒng)的時(shí)間約束,則認(rèn)為系統(tǒng)失效。
上下文切換
發(fā)生中斷后分配新任務(wù)的過程中隱含著上下文切換。這個(gè)過程在中斷時(shí)存儲(chǔ) CPU 的當(dāng)前狀態(tài),然后恢復(fù)一項(xiàng)給定任務(wù)的狀態(tài)。上下文切換依賴于操作系統(tǒng)及底層的處理器架構(gòu)。
換句話說,系統(tǒng)面對(duì)變化的負(fù)載(從最小到最壞的情況)時(shí)必須確定性地保證滿足時(shí)間要求。注意,上述定義并未提到性能,原因是實(shí)時(shí)性與速度關(guān)系不大:它與可預(yù)見性有關(guān)。例如,使用快速的現(xiàn)代處理器時(shí),Linux 可以提供 20 μ 微秒的典型中斷響應(yīng),但有時(shí)候響應(yīng)會(huì)變得很長(zhǎng)。這是一個(gè)基本的問題:并不是 Linux 不夠快或效率不夠高,而是因?yàn)樗荒芴峁┐_定性。
一些例子將演示全部這些內(nèi)容的含意。圖 1 顯示的是中斷延遲指標(biāo)。當(dāng)中斷到達(dá)時(shí)(event),CPU 發(fā)生中斷并轉(zhuǎn)入中斷處理。執(zhí)行一些工作以確定發(fā)生了什么事件,然后執(zhí)行少量工作分配必需的任務(wù)以處理此事件(上下文切換)。中斷到達(dá)與分發(fā)必需任務(wù)之間的時(shí)間(假設(shè)分配的是優(yōu)先級(jí)最高的任務(wù))稱為響應(yīng)時(shí)間。對(duì)于實(shí)時(shí)性要求,響應(yīng)時(shí)間應(yīng)是確定的并應(yīng)當(dāng)在已知的最壞情況的時(shí)間內(nèi)完成。
圖 1. 中斷延遲和響應(yīng)時(shí)間
有關(guān)這個(gè)過程的一個(gè)例子就是目前汽車中使用的氣囊。當(dāng)報(bào)告車輛碰撞的傳感器中斷 CPU 后,操作系統(tǒng)應(yīng)快速地分配展開氣囊的任務(wù),并且不允許其他非實(shí)時(shí)處理進(jìn)行干擾。晚一秒鐘展開氣囊比沒有氣囊的情況更糟糕。
除為中斷處理提供確定性外,實(shí)時(shí)處理也需要支持周期性間隔的任務(wù)調(diào)度??紤]圖 2。本圖演示了周期性任務(wù)調(diào)度。大量控制系統(tǒng)要求周期性采樣與處理。某個(gè)特定任務(wù)必須按照固定的周期(p)執(zhí)行,從而確保系統(tǒng)的穩(wěn)定性。考慮一下汽車的防抱死系統(tǒng)(ABS)??刂葡到y(tǒng)對(duì)車輛的每個(gè)車輪的轉(zhuǎn)速進(jìn)行采樣(每秒最多 20 次)并控制每個(gè)制動(dòng)器的壓力(防止它鎖死)。為了保持控制系統(tǒng)的正常工作,傳感器的采樣與控制必須按照一定的周期間隔。這意味著必須搶占其他處理,以便 ABS 任務(wù)能按照期望的周期執(zhí)行。
圖 2. 周期性任務(wù)調(diào)度
硬實(shí)時(shí)與軟實(shí)時(shí)系統(tǒng)
能夠在指定的期限完成實(shí)時(shí)任務(wù)(即便在最壞的處理負(fù)載下也能如此)的操作系統(tǒng)稱為硬實(shí)時(shí) 系統(tǒng)。但并不是任何情況下都需要硬實(shí)時(shí)支持。如果操作系統(tǒng)在平均情況下能支持任務(wù)的執(zhí)行期限,則稱它為軟實(shí)時(shí) 系統(tǒng)。硬實(shí)時(shí)系統(tǒng)指超過截止期限后將造成災(zāi)難性后果(例如展開氣囊過晚或制動(dòng)壓力產(chǎn)生的滑行距離過長(zhǎng))的系統(tǒng)。軟實(shí)時(shí)系統(tǒng)超過截止期限后并不會(huì)造成系統(tǒng)整體失?。ㄈ鐏G失視頻中的一幀)。
現(xiàn)在您已經(jīng)對(duì)實(shí)時(shí)性要求有了一些深入了解,讓我們查看一些實(shí)時(shí) Linux 架構(gòu)各支持哪個(gè)級(jí)別的實(shí)時(shí)性以及如何做到這一點(diǎn)。
瘦內(nèi)核方法
瘦內(nèi)核(或微內(nèi)核)方法使用了第二個(gè)內(nèi)核作為硬件與 Linux 內(nèi)核間的抽象接口(見圖 3)。非實(shí)時(shí) Linux 內(nèi)核在后臺(tái)運(yùn)行,作為瘦內(nèi)核的一項(xiàng)低優(yōu)先級(jí)任務(wù)托管全部非實(shí)時(shí)任務(wù)。實(shí)時(shí)任務(wù)直接在瘦內(nèi)核上運(yùn)行。
圖 3. 硬實(shí)時(shí)的瘦內(nèi)核方法
瘦內(nèi)核主要用于(除了托管實(shí)時(shí)任務(wù)外)中斷管理。瘦內(nèi)核截取中斷以確保非實(shí)時(shí)內(nèi)核無法搶占瘦內(nèi)核的運(yùn)行。這允許瘦內(nèi)核提供硬實(shí)時(shí)支持。
雖然瘦內(nèi)核方法有自己的優(yōu)勢(shì)(硬實(shí)時(shí)支持與標(biāo)準(zhǔn) Linux 內(nèi)核共存),但這種方法也有缺點(diǎn)。實(shí)時(shí)任務(wù)和非實(shí)時(shí)任務(wù)是獨(dú)立的,這造成了調(diào)試?yán)щy。而且,非實(shí)時(shí)任務(wù)并未得到 Linux 平臺(tái)的完全支持(瘦內(nèi)核執(zhí)行稱為瘦 的一個(gè)原因)。
使用這種方法的例子有 RTLinux (現(xiàn)在由 Wind River Systems 專有),實(shí)時(shí)應(yīng)用程序接口(RTAI)和 Xenomai。
超微內(nèi)核方法
這里瘦內(nèi)核方法依賴于包含任務(wù)管理的最小內(nèi)核,而超微內(nèi)核法對(duì)內(nèi)核進(jìn)行更進(jìn)一步的縮減。通過這種方式,它不像是一個(gè)內(nèi)核而更像是一個(gè)硬件抽象層(HAL)。超微內(nèi)核為運(yùn)行于更高級(jí)別的多個(gè)操作系統(tǒng)提供了硬件資源共享(見圖 4)。因?yàn)槌?nèi)核對(duì)硬件進(jìn)行了抽象,因此它可為更高級(jí)別的操作系統(tǒng)提供優(yōu)先權(quán),從而支持實(shí)時(shí)性。
圖 4. 對(duì)硬件進(jìn)行抽象的超微內(nèi)核法
注意,這種方法和運(yùn)行多個(gè)操作系統(tǒng)的虛擬化方法有一些相似之處。使用這種方法的情況下,超微內(nèi)核在實(shí)時(shí)和非實(shí)時(shí)內(nèi)核中對(duì)硬件進(jìn)行抽象。這與 hypervisor 從客戶(guest)操作系統(tǒng)對(duì)裸機(jī)進(jìn)行抽象的方式很相似。
關(guān)于超微內(nèi)核的示例是操作系統(tǒng)的 Adaptive Domain Environment for Operating Systems (ADEOS)。ADEOS 支持多個(gè)并發(fā)操作系統(tǒng)同步運(yùn)行。當(dāng)發(fā)生硬件事件后,ADEOS 對(duì)鏈中的每個(gè)操作系統(tǒng)進(jìn)行查詢以確定使用哪一個(gè)系統(tǒng)處理事件。
資源內(nèi)核法
另一個(gè)實(shí)時(shí)架構(gòu)是資源內(nèi)核法。這種方法為內(nèi)核增加一個(gè)模塊,為各種資源提供預(yù)留(reservation)。這種機(jī)制保證了對(duì)時(shí)分復(fù)用(time-multiplexed)系統(tǒng)資源的訪問(CPU、網(wǎng)絡(luò)或磁盤帶寬)。這些資源擁有多個(gè)預(yù)留參數(shù),如循環(huán)周期、需要的處理時(shí)間(也就是完成處理所需的時(shí)間),以及截止時(shí)間。
資源內(nèi)核提供了一組應(yīng)用程序編程接口(API),允許任務(wù)請(qǐng)求這些預(yù)留資源(見圖 5)。然后資源內(nèi)核可以合并這些請(qǐng)求,使用任務(wù)定義的約束定義一個(gè)調(diào)度,從而提供確定的訪問(如果無法提供確定性則返回錯(cuò)誤)。通過調(diào)度算法,如 Earliest-Deadline-First (EDF),內(nèi)核可以處理動(dòng)態(tài)的調(diào)度負(fù)載。
圖 5. 實(shí)現(xiàn)資源預(yù)留的資源內(nèi)核法
資源內(nèi)核法實(shí)現(xiàn)的一個(gè)示例是 CMU 公司的 Linux/RK,它把可移植的資源內(nèi)核集成到 Linux 中作為一個(gè)可加載模塊。這種實(shí)現(xiàn)演化成商用的 TimeSys Linux/RT 產(chǎn)品。
標(biāo)準(zhǔn) 2.6 內(nèi)核中的實(shí)時(shí)
目前探討的這些方法在架構(gòu)上都很有趣,但是它們都在內(nèi)核的外圍運(yùn)行。然而,如果對(duì)標(biāo)準(zhǔn) Linux 內(nèi)核進(jìn)行必要的修改使其支持實(shí)時(shí)性,結(jié)果會(huì)怎么樣呢?
今天,在 2.6 內(nèi)核中,通過對(duì)內(nèi)核進(jìn)行簡(jiǎn)單配置使其完全可搶占(見圖 6),您就可以得到軟實(shí)時(shí)功能。在標(biāo)準(zhǔn) 2.6 Linux 內(nèi)核中,當(dāng)用戶空間的進(jìn)程執(zhí)行內(nèi)核調(diào)用時(shí)(通過系統(tǒng)調(diào)用),它便不能被搶占。這意味著如果低優(yōu)先級(jí)進(jìn)程進(jìn)行了系統(tǒng)調(diào)用后,高優(yōu)先級(jí)進(jìn)程必須等到調(diào)用結(jié)束后才能訪問 CPU。新的配置選項(xiàng) CONFIG_PREEMPT 改變了這一內(nèi)核行為,在高優(yōu)先級(jí)任務(wù)可用的情況下(即使此進(jìn)程正在進(jìn)行系統(tǒng)調(diào)用),它允許進(jìn)程被搶占。
圖 6 允許搶占的標(biāo)準(zhǔn) 2.6 Linux 內(nèi)核
但這種配置選項(xiàng)也是一種折衷。雖然此選項(xiàng)實(shí)現(xiàn)了軟實(shí)時(shí)性能并且即使在負(fù)載條件下也可使操作系統(tǒng)順利地運(yùn)行,但這樣做也付出了代價(jià)。代價(jià)就是略微減低了吞吐量以及內(nèi)核性能,原因是 CONFIG_PREEMPT 選項(xiàng)增加了開銷。這種選項(xiàng)對(duì)桌面和嵌入式系統(tǒng)而言是有用的,但并不是在任何場(chǎng)景下都有用(例如,服務(wù)器)。
新的 O(1) 調(diào)度程序
2.6 內(nèi)核中新的 O(1) 調(diào)度程序?qū)π阅苡泻艽蟮奶嵘词勾嬖诤芏嗳蝿?wù)的情況下也是如此。不管需要運(yùn)行的任務(wù)有多少個(gè),新的調(diào)度程序都會(huì)在有限的時(shí)間內(nèi)運(yùn)行。
在 2.6 內(nèi)核中另一項(xiàng)有用的配置選項(xiàng)是高精度定時(shí)器。這個(gè)新選項(xiàng)允許定時(shí)器以 1μs 的精度運(yùn)行(如果底層硬件支持的話),并通過紅黑樹實(shí)現(xiàn)對(duì)定時(shí)器的高效管理。通過紅黑樹,可以使用大量的定時(shí)器而不會(huì)對(duì)定時(shí)器子系統(tǒng)(O(log n))的性能造成影響。
只需要一點(diǎn)額外的工作,您就可以通過 PREEMPT_RT 補(bǔ)丁實(shí)現(xiàn)硬實(shí)時(shí)。PREEMPT_RT 補(bǔ)丁提供了多項(xiàng)修改,可實(shí)現(xiàn)硬實(shí)時(shí)支持。其中一些修改包括重新實(shí)現(xiàn)一些內(nèi)核鎖定原語,從而實(shí)現(xiàn)完全可搶占,實(shí)現(xiàn)內(nèi)核互斥的優(yōu)先級(jí)繼承,并把中斷處理程序轉(zhuǎn)換為內(nèi)核線程以實(shí)現(xiàn)線程可搶占。
結(jié)束語
Linux 不僅是一個(gè)實(shí)驗(yàn)和描述實(shí)時(shí)算法的理想平臺(tái),目前在標(biāo)準(zhǔn)的 2.6 內(nèi)核中也實(shí)現(xiàn)了實(shí)時(shí)功能。從標(biāo)準(zhǔn)內(nèi)核中您可以實(shí)現(xiàn)軟實(shí)時(shí)功能,再執(zhí)行一些額外的工作(內(nèi)核補(bǔ)?。┠涂梢詷?gòu)建硬實(shí)時(shí)應(yīng)用程序。
本文簡(jiǎn)要介紹了一些為 Linux 內(nèi)核提供實(shí)時(shí)計(jì)算的技術(shù)。很多早期的嘗試使用瘦內(nèi)核方法把實(shí)時(shí)任務(wù)與標(biāo)準(zhǔn)內(nèi)核分離。后來,出現(xiàn)了超微內(nèi)核法,它與如今的虛擬化解決方案中使用的 hypervisor 非常相似。最后,Linux 內(nèi)核提供了自己的實(shí)時(shí)方法,包括軟實(shí)時(shí)和硬實(shí)時(shí)。
評(píng)論