一、前言
實時性(RealTime/Real-Time)是嵌入式軟件領(lǐng)域一個關(guān)鍵性能指標,也是計算機系統(tǒng)領(lǐng)域一個老生常談的話題。本文將從工程實踐的角度系統(tǒng)性描述軟件實時性的概念、影響軟件實時性的因素,以及如何提高軟件實時性。雖部分內(nèi)容是基于Linux描述,但相關(guān)思想和方法也適用于其它通用操作系統(tǒng)(General Purpose Operating System,后文簡稱OS)。Linux的應(yīng)用非常廣泛,相關(guān)問題比較有代表性,且是開源軟件,資源比較豐富,相應(yīng)的性能提升也能帶來更大的價值。掌握OS的基本概念如中斷、異常、線程、調(diào)度等有助于更好的理解本文。
二、實時性概述
2.1 實時性概念
很多人容易對實時性產(chǎn)生誤解,認為實時性是衡量完成一個任務(wù)的最快時間。相反實時性關(guān)注的不是完成一個任務(wù)的最快時間,而是完成這個任務(wù)的最差時間。在對實時性進行更深入探討前,先簡單回顧下軟件實時性問題的由來。實時性的概念是伴隨著OS產(chǎn)生的,在沒有OS之前,基于圖靈機模型的計算機按照邏輯串行執(zhí)行指令,在系統(tǒng)層面不存在影響任務(wù)實時性和確定性的因素。隨著軟硬件技術(shù)的發(fā)展,有了OS、中斷處理、調(diào)度、搶占、臨界區(qū)、SMP等概念,影響實時性的一些關(guān)鍵要素就出現(xiàn)了(雖然裸機也有中斷,但不是本文關(guān)注點)。
在某些應(yīng)用場景,如果任務(wù)實時性不達標,會導(dǎo)致非常嚴重的后果如交通、航天、醫(yī)療等安全關(guān)鍵領(lǐng)域,因此實時性在這些領(lǐng)域是一個非常重要的技術(shù)指標。維基百科對計算機領(lǐng)域?qū)崟r的定義已非常準確,直接引用如下:
Atask in a software-controlled system is called real-time (or "executable in real-time, in real-time") if the combined response and execution time of the task is less than the maximum time allowed, taking into account outside influences.
簡單總結(jié)即“響應(yīng)時間+執(zhí)行時間小于允許的最大時間,則稱為實時”。使用圖1的模型表示實時的概念會更形象一些:
圖1 實時性概念
CPU按序執(zhí)行指令流,在T0時刻發(fā)生外部中斷(也適用于如信號量、文件描述符事件等內(nèi)部事件),CPU因為某些因素在經(jīng)過一段時間的延遲后進入事件響應(yīng)函數(shù),此時定義為T1,從進入事件響應(yīng)函數(shù)到事件完全處理完成,到達T2結(jié)束完成整個事件處理流程。為了統(tǒng)一語言,把T0~T1描述為響應(yīng)時間也稱為延遲Latency,T1~T2描述為任務(wù)處理時間,把M稱為Deadline,按照這種方式劃分,可適用于任何對實時性有要求的場景。如外部事件是中斷,則T0~T1為中斷響應(yīng)時間或中斷延遲,T1~T2為中斷處理時間;如外部事件是一個資源就緒的調(diào)度事件,則T0~T1為調(diào)度響應(yīng)時間或調(diào)度延遲,T1~T2為調(diào)度處理時間。響應(yīng)時間/處理時間的最大值與最小值之間的差值,稱為抖動Jitter,對于需要周期性完成的任務(wù)來說抖動是很重要的一個指標。任務(wù)在執(zhí)行過程中發(fā)生切換,稱之為搶占,實時任務(wù)對非實時任務(wù)的搶占是確保實時性非常重要的機制。
關(guān)于實時性還有硬實時和軟實時的概念,圖1中若”T2 - T0 < M”恒為真則為硬實時,而如果是基于一定條件使”T2 - T0 < M”為真則為軟實時,如T2 - T0在一段時間內(nèi)的平均值小于Deadline,則可以稱為軟實時。
Deadline是一個期望值,根據(jù)需求確定,但是T2-T0卻是一個動態(tài)值,在不同的應(yīng)用場景或者系統(tǒng)內(nèi)外部狀態(tài)下值是不同的,也就是上文說的抖動,如何找到Max(T2-T0)就是對實時性進行驗證的關(guān)鍵。業(yè)界通常使用可調(diào)度性分析對軟件實時性、確定性進行驗證,ISO26262對高功能安全等級軟件的可調(diào)度性分析是強制要求。可調(diào)度性分析可通過對系統(tǒng)軟件架構(gòu)(必要時分析可深入至代碼級)的數(shù)據(jù)流、控制流、執(zhí)行路徑的分析,構(gòu)造對應(yīng)的測試用例,通過測試驗證系統(tǒng)的可調(diào)度性,如Linux常用的cycletest就是通過測試對系統(tǒng)的實時性進行驗證。對實時應(yīng)用(后簡稱RT App)執(zhí)行的實時性驗證,需要計算應(yīng)用處理的最大時間和最長執(zhí)行路徑,在計算機系統(tǒng)領(lǐng)域通常使用最差執(zhí)行時間(Worst-case execution time,簡稱WCET)表示,WCET的計算和驗證也有多種方法,包括抽象解釋、靜態(tài)分析、測試驗證等。關(guān)于實時性的驗證,內(nèi)容非常的多,為了確保本文不發(fā)散,這里僅做概念介紹,不再深入分析。
為了確?!盩2 - T0 < M”,在M是常量的情況下,需要減少T0~T2的時間跨度,并在這個時間跨度內(nèi)合理的分配響應(yīng)和處理時間。對于開放式OS,其部署多個具備不同業(yè)務(wù)特征且Deadline不同的實時任務(wù),單純的依靠OS提供的調(diào)度策略或?qū)崟r性機制很難保證系統(tǒng)內(nèi)所有實時任務(wù)滿足其Deadline,需要配合任務(wù)的到達時間arrive time、松弛時間slack time等進行定量分析計算并制定相應(yīng)的調(diào)度策略。
2.2影響實時性的關(guān)鍵因素
在討論影響軟件實時性因素之前,需要界定一個范圍,因為影響實時性的因素太多,芯片、內(nèi)存(cache)、外設(shè)、軟件等等。通常來說硬件特性會顯著影響軟件的執(zhí)行速度,如CPU是否多核,主頻高低,是否有MMU,是否有特權(quán)級切換,是否有cache,幾級cache,CPU是否動態(tài)調(diào)頻,內(nèi)存是什么介質(zhì),訪問方式是UMA還是NUMA等?進而影響系統(tǒng)實時性,但這部分內(nèi)容與特定平臺相關(guān),為避免發(fā)散本文僅討論軟件因素。
為了統(tǒng)一共識,這里限定一個具體的場景,該場景能將影響實時性的相關(guān)因素都串起來,后續(xù)的分析也基于此:“實時應(yīng)用RT App阻塞等待某OS資源,而該資源又依賴外部中斷”,場景可實例化為RT App通過read接口阻塞在網(wǎng)絡(luò)socket上,系統(tǒng)在socket數(shù)據(jù)就緒后喚醒RT App任務(wù)讀取網(wǎng)卡報文,并完成數(shù)據(jù)處理。
按照圖1的模型,外部事件為網(wǎng)卡中斷,T0~T1為網(wǎng)卡驅(qū)動與協(xié)議棧處理并喚醒阻塞在read調(diào)用的任務(wù),即網(wǎng)絡(luò)報文的響應(yīng)時間;而T1~T2是RT App對網(wǎng)絡(luò)報文的處理時間。先從OS負責的響應(yīng)時間部分開始如圖2,這里將響應(yīng)時間T0~T1繼續(xù)分解,得出如下幾個點:
T0:外部發(fā)生網(wǎng)卡物理中斷
T01:CPU進入中斷處理程序(Interrupt Service Routine)ISR
T02:完成網(wǎng)卡驅(qū)動與協(xié)議棧處理喚醒目標線程,也稱就緒時間或Arrival Time
T03:目標線程被選為CPU的當前任務(wù)
圖2 響應(yīng)時間分解
實際環(huán)境中,在上述幾個時間點之間仍然可能會出現(xiàn)新的中斷、異常、非預(yù)期調(diào)度、負載均衡等(實際系統(tǒng)在做實時性優(yōu)化時需要盡量避免這些情況發(fā)生),但是這些行為最終回歸到上述四個步驟,不影響本文分析。
從上圖可以看出,在操作系統(tǒng)層面,影響任務(wù)實時性的關(guān)鍵因素有這四個:
- T0~T01中斷延遲(外部中斷發(fā)生到CPU執(zhí)行中斷處理程序間的延遲)
- T01~T02中斷處理開銷(為了簡化模型,把一些內(nèi)核功能如協(xié)議棧的開銷也算在中斷處理里了)
- T02~T03調(diào)度延遲(任務(wù)等待的資源就緒,到CPU選定目標任務(wù)之間的延遲)
- T03~T1調(diào)度開銷(上下文切換,返回到用戶態(tài)RT App阻塞點)
T0~T01中斷延遲主要由受系統(tǒng)關(guān)中斷影響,因為中斷發(fā)生時系統(tǒng)可能處于關(guān)中斷狀態(tài),在關(guān)中斷狀態(tài)下CPU會暫時屏蔽外部信號,在打開中斷后才響應(yīng)該外部中斷。如系統(tǒng)當前正在執(zhí)行的代碼不能被中斷打斷時,調(diào)用接口屏蔽外部中斷,處理完成后再打開外部中斷。顯然關(guān)中斷的代碼范圍越大執(zhí)行時間越長,可能的中斷延遲也會越大。對于支持中斷優(yōu)先級的芯片,還受中斷優(yōu)先級影響,高優(yōu)先級中斷會優(yōu)先于低優(yōu)先級中斷被處理。
T01~T02中斷處理開銷主要受中斷處理邏輯復(fù)雜度影響,操作系統(tǒng)為提高中斷處理速度,通常會分段處理中斷,把一些關(guān)鍵性操作放在ISR中處理,這部分代碼必須處于關(guān)中斷狀態(tài)運行。把更耗時的操作在開中斷狀態(tài)下執(zhí)行,如Linux的軟中斷機制,再比如微內(nèi)核架構(gòu)的OS會將復(fù)雜的中段處理放在用戶態(tài)線程處理。在OS內(nèi)核處理中斷或者其它必要流程中可能會訪問臨界區(qū),這時會使用自旋鎖或者互斥鎖,這些操作也會影響中斷處理時長,進而影響整個系統(tǒng)實時性。在工程實踐上影響內(nèi)核實時性、確定性很多時候都是這些臨界區(qū)訪問導(dǎo)致的。所有中斷相關(guān)的處理工作完成后,OS通過調(diào)度接口喚醒目標任務(wù)進入下一階段。
圖3 Linux應(yīng)用運行模型
T02~T03調(diào)度延遲主要受系統(tǒng)關(guān)調(diào)度(也稱關(guān)搶占)、調(diào)度點(也稱搶占點)的影響。當目標任務(wù)所需資源就緒時,目標任務(wù)所在的CPU上下文可能處于關(guān)調(diào)度的狀態(tài),禁止搶占,必須等待打開調(diào)度后才能發(fā)生調(diào)度行為,同關(guān)中斷一樣,關(guān)調(diào)度的范圍越大,可能的調(diào)度延遲也會越大,遇到這種情況OS一般會設(shè)置一個標志,等待調(diào)度發(fā)生。同時由于調(diào)度是軟件行為,必須有調(diào)度點才能發(fā)生調(diào)度,即目標任務(wù)就緒,目標任務(wù)所在CPU也處于可調(diào)度狀態(tài),此時需要有合適的調(diào)度點讓CPU發(fā)生調(diào)度行為。調(diào)度點又有主動調(diào)度點和系統(tǒng)調(diào)度點。主動調(diào)度點是指調(diào)用了可能引起阻塞的函數(shù)引起系統(tǒng)調(diào)度,而系統(tǒng)調(diào)度點是指系統(tǒng)在運行過程中的調(diào)度,非應(yīng)用主動發(fā)起,也稱搶占點,即當前任務(wù)在未主動讓出CPU的情況下被動發(fā)生的調(diào)度,如Linux內(nèi)核中斷處理完成或者從內(nèi)核態(tài)返回用戶態(tài)時。
T03~T1調(diào)度開銷是系統(tǒng)的基礎(chǔ)開銷,受場景和OS具體實現(xiàn)影響如是同一地址空間內(nèi)線程切換還是進程間切換、是否有特權(quán)級切換、是否實時線程、采用哪種調(diào)度策略、是否有資源配額限制等,這些因素會顯著的影響調(diào)度的開銷。當調(diào)度發(fā)生,已就緒的目標線程是否被選為當前任務(wù)取決于系統(tǒng)的調(diào)度策略。如Linux默認采用的公平調(diào)度算法,任務(wù)根據(jù)動態(tài)優(yōu)先級共享CPU。這在很大程度上保證了系統(tǒng)的公平,卻導(dǎo)致實時性的降低。此時基于優(yōu)先級的調(diào)度策略就派上了用場,當高優(yōu)先級任務(wù)就緒時,搶占低優(yōu)先級任務(wù),不管低優(yōu)先級任務(wù)是否完成,一般的實時OS均支持基于優(yōu)先級的調(diào)度策略。使用優(yōu)先級的調(diào)度策略,在使用加鎖的共享資源時,可能會遇到優(yōu)先級反轉(zhuǎn)問題,導(dǎo)致高優(yōu)先級任務(wù)的實時性降低。另外系統(tǒng)中可能存在多個實時任務(wù),影響多個實時任務(wù)的實時性的因素還包括這些實時任務(wù)的DeadLine的先后以及任務(wù)執(zhí)行時機,僅按優(yōu)先級處理也可能會導(dǎo)致任務(wù)DeadLine的失守。
表1:
至此完成影響系統(tǒng)響應(yīng)時間的分析,總結(jié)內(nèi)容如表1。下面對RT App負責的T1~T2處理時間進行分析,從應(yīng)用編程的角度出發(fā),RT App被喚醒后有一般三種運行模式:
1.執(zhí)行計算邏輯
2.執(zhí)行系統(tǒng)調(diào)用,訪問系統(tǒng)資源
3.線程間、進程間通信
工程真實場景是上述三種情況的各種可能組合,但是影響實時性的因素主要與上述三種情況有關(guān)。
刨除RT App業(yè)務(wù)自身算法邏輯、調(diào)試、BUG等對計算時間的影響,在計算資源充足的情況下,影響計算邏輯時長的可能因素主要是內(nèi)外部事件的打斷和搶占。關(guān)于內(nèi)外部事件打斷,是指RT App在執(zhí)行過程中頻繁被外設(shè)中斷、異常、信號等打斷,這些打斷會顯著的影響應(yīng)用執(zhí)行的確定性。中斷一般屬于不可屏蔽事件,如系統(tǒng)定時器、各種外設(shè)的IO訪問;異常最常見的是缺頁異常,OS為提高應(yīng)用內(nèi)存使用效率,對物理內(nèi)存的映射是延遲執(zhí)行的,如在缺頁異常中完成,當任務(wù)首次訪問某內(nèi)存頁面或首次執(zhí)行某代碼段時,會造成缺頁異常,觸發(fā)相應(yīng)的內(nèi)存分配、映射機制,這部分操作的不確定性會影響任務(wù)的計算時間。內(nèi)存回收是指OS可用內(nèi)存低于某個水線時,系統(tǒng)對可回收內(nèi)存如cache進行回收,之后再重新分配給應(yīng)用,這個過程可能比較耗時,進而影響內(nèi)存分配的實時性,在某些極端情況下觸發(fā)OOM(Out Of Memory)和LMK(Low Memory Killer),會導(dǎo)致更多非預(yù)期行為。關(guān)于信號是指POSIX信號,OS一般會在特權(quán)級切換時處理信號事件,這也會導(dǎo)致任務(wù)的計算被延遲。關(guān)于搶占,與任務(wù)本身的計算無關(guān)了,是當前任務(wù)被更高優(yōu)先級的任務(wù)搶占或者由于配置了cgroup等配額管理導(dǎo)致沒有計算資源可用。除此之外,在某些架構(gòu)的處理器上可能還有一些調(diào)試異常、字節(jié)非對齊異常等打斷任務(wù)的執(zhí)行。
RT App執(zhí)行系統(tǒng)調(diào)用,又有幾種情況,一種是阻塞式系統(tǒng)調(diào)用,阻塞時長的不確定性會導(dǎo)致Deadline的失守,如waitpid;第二種情況是該系統(tǒng)調(diào)用本身比較慢,如操作串口IO的printf,串口打印會顯著拖慢應(yīng)用的執(zhí)行速度就是這個原因。還有一種情況是該系統(tǒng)調(diào)用本身不會阻塞,但是在該系統(tǒng)調(diào)用的實現(xiàn)中訪問了全局資源導(dǎo)致阻塞。
在多核多任務(wù)系統(tǒng)上線程間同步互斥或者進程間通信可能會導(dǎo)致當前任務(wù)的阻塞,也會顯著的影響計算確定性,進而導(dǎo)致Deadline的失守,如mutex lock。
站在OS的角度看影響T1~T2處理時間的因素,就兩個:
1.線程執(zhí)行的非預(yù)期打斷
2.可能導(dǎo)致線程阻塞的調(diào)度行為
圖4 APP視角的運行模型
站在目標任務(wù)Rt App的角度上,影響T1~T2處理時間的因素就一個即RT App讓出CPU去執(zhí)行其它代碼。畢竟CPU永遠都是在按照設(shè)計流程執(zhí)行計算,并無刻意偷懶。
除此之外系統(tǒng)對計算資源的分配也會顯著影響任務(wù)的實時性。如圖5:a、b、c三個同優(yōu)先級的任務(wù)同時到達,如果按圖示的執(zhí)行順序執(zhí)行則只有Da(a任務(wù)的Deadline)能滿足,其它兩個任務(wù)的Deadline都會失守,但如果把a任務(wù)的執(zhí)行適當延遲到b、c任務(wù)之后,則可以保證三個任務(wù)的目標Deadline都滿足。
圖5 實時任務(wù)調(diào)度
通過上述分析,可以看出影響任務(wù)實時性的主要因素基本與中斷(包含內(nèi)部中斷和外部中斷)、調(diào)度時機、調(diào)度策略、資源分配有關(guān),掌握這些原理能幫助研發(fā)人員更好的理解實時性問題的分析和解決方法。
三、如何解決實時性問題
3.1 實時性問題分析
書接上文,在動手解決系統(tǒng)實時性問題前,需要先明確系統(tǒng)的實時性瓶頸在哪里,根因是什么,以及制定優(yōu)化后的目標。不同的系統(tǒng)、不同的場景,其面臨的實時性需求差異很大,沒有統(tǒng)一的答案,甚至沒有統(tǒng)一的方法。留下本章節(jié)的目的主要是想說明這部分內(nèi)容的重要性,后續(xù)的優(yōu)化措施都是從這里出發(fā),可根據(jù)第二章節(jié)的描述,大膽假設(shè)、小心求證,一步步接近真相。有道無術(shù),尚可求也,若需求或者方向錯了,一切皆是惘然。
3.2 RT App的實時優(yōu)化
據(jù)2.2章節(jié)分析所述影響RtApp實時性的因素主要是內(nèi)外部事件打斷和調(diào)度引起的阻塞。這兩種因素都可以視為外部干擾,針對干擾,最好的優(yōu)化措施是防止干擾,次之是降低干擾,安全OS一般都提供了豐富的免打擾機制。免于干擾是一個非常重要的安全功能,它能提高系統(tǒng)的實時性、確定性、安全性,在進行安全相關(guān)業(yè)務(wù)的開發(fā)和部署時一定要充分利用免于干擾的特性。
Linux、Unix、QNX等POSIX OS的很多免于干擾機制都是在進程上生效的,因此實時任務(wù)要和其它通用任務(wù)做隔離,即使是實時任務(wù)間仍然可以使用線程隔離運行。在資源允許的情況下,可以使用核隔離加親和性綁定的機制保證實時任務(wù)的運行隔離,使用isolcpus參數(shù)隔離出獨立的CPU核用作實時任務(wù)的運行,加上親和性綁定,可以保證除內(nèi)核必要的系統(tǒng)線程外,沒有其它線程能干擾到綁定到隔離核上實時任務(wù)的運行。對于內(nèi)存使用導(dǎo)致的缺頁異?;蛘呖赡艿姆峙洳患皶r,可以使用預(yù)先分配內(nèi)存資源加mlockall資源鎖定的方法解決。RtApp在啟動后可以預(yù)先將所需的內(nèi)存資源全部申請好,然后使用mlockall將所有資源鎖定,在后續(xù)的執(zhí)行過程中就不會存在向系統(tǒng)申請資源的情況。資源的預(yù)先申請可以使用動態(tài)申請的方式,也可以使用靜態(tài)分配的方式。靜態(tài)分配的方式確定性更好也是功能安全相關(guān)標準強烈推薦的內(nèi)存使用方式,但是需要RtApp在設(shè)計實現(xiàn)時就確定相關(guān)資源;動態(tài)申請的方式需要RtApp先從內(nèi)核將資源申請好,然后在用戶態(tài)由應(yīng)用自己維護內(nèi)存池,提供定制化的動態(tài)申請釋放接口,gibc庫也有一定緩存管理機制,但是不一定滿足應(yīng)用的定制化訴求。不管是哪種方式,核心思想都是在使用資源時保證其確定性,而不是和系統(tǒng)中的其它任務(wù)競爭。
圖6免于干擾的模型
除了對實時任務(wù)進行設(shè)置外,還可以通過對其它非實時任務(wù)進行限制排除或降低運行干擾。在運行上可以通過調(diào)整非實時任務(wù)的優(yōu)先級降低其CPU使用率,也可以通過一些工具如cpulimit、nice等命令控制任務(wù)的CPU占用率,控制組cgroup機制功能強大,可控制包含CPU、內(nèi)存等資源的使用,也可使用POSIX接口setrlimit控制內(nèi)存等資源使用上限。
對于因RtApp主動調(diào)度降低實時性的問題,需要靠RtApp在設(shè)計實現(xiàn)時避免使用此類接口,避免使用臨界區(qū),通常規(guī)則是在做實時操作時可以釋放資源如鎖、信號量等,但是不要獲取資源。對于阻塞式操作如IO操作,可以使用POSIX規(guī)范設(shè)置IO_NONBLOCK非阻塞工作模式,在該模式下IO操作以非阻塞模式運行,任務(wù)根據(jù)資源的就緒情況進行處理。對于被搶占,需要根據(jù)系統(tǒng)可調(diào)度性分析結(jié)果,根據(jù)需求合理的設(shè)計各任務(wù)之間的調(diào)度策略、優(yōu)先級、任務(wù)執(zhí)行時機等,同時在實時任務(wù)間進行互斥時,使用帶有優(yōu)先級繼承的mutex鎖,防止出現(xiàn)反轉(zhuǎn)。
關(guān)于調(diào)度策略和計算資源在多實時任務(wù)間的分配,這里以Linux為例介紹一下常見的調(diào)度策略,其中非實時調(diào)度策略為:SCHED_OTHER、SCHED_BATCH、SCHED_IDLE,這三個調(diào)度策略大同小異,都是基于動態(tài)nice值的公平調(diào)度。實時調(diào)度策略為:SCHED_FIFO、SCHED_RR、SCHED_DEADLINE。SCHED_RR和SCHED_FIFO都是基于固定優(yōu)先級的調(diào)度策略,其中RR相較于FIFO的區(qū)別在與優(yōu)先級相同情況下是否會主動讓出CPU,而SCHED_DEADLINE是根據(jù)Deadline的先后來調(diào)度的也就是EDF調(diào)度算法,EDF可搶占FIFO、RR的任務(wù)。在進行計算資源分配時需要結(jié)合業(yè)務(wù)特征選擇合適的調(diào)度算法,防止出現(xiàn)圖5情況的發(fā)生。
針對一些其它打斷如軟硬中斷太多,可通過親和性設(shè)置把中斷和軟中斷線程綁定到其他核上;對定時信號打斷可更換定時器的使用方式為timerfd,在資源允許的情況下對于一些場景,還可能使用輪詢模式代替中斷模式來提高實時性,但是此類情況需要具體問題具體分析了。
針對自動駕駛應(yīng)用場景,普遍使用CPU、GPU、BPU、DSP、NPU等異構(gòu)核混合計算,存在大量任務(wù)覆蓋感知、規(guī)劃、決策全流程,基于事件驅(qū)動并完全交由OS編排調(diào)度,存在任務(wù)執(zhí)行抖動大的問題。而基于有向無環(huán)圖的方式組織計算任務(wù),并根據(jù)圖的特性對任務(wù)進行編排能大大提高任務(wù)的實時性,這種方法降低了任務(wù)運行確定性對于OS的依賴,且保持較高的靈活性,百度Apollo的Cyber以及英偉達DriveWorks的CGF均使用了該方法。
總結(jié)下來對于提高任務(wù)實時性的核心思想就是通過使用確定性資源,隔離或減少外部干擾,避免執(zhí)行被非預(yù)期打斷達到時間、空間的確定性,對于多任務(wù)場景還需要結(jié)合其它任務(wù)的特征選擇合適的調(diào)度策略。
3.3 OS實時優(yōu)化方案
在給出具體的優(yōu)化措施分析前,回到表1分析出的影響實時性的關(guān)鍵因素,從源頭出發(fā),給出解決OS實時性問題的思路,如表2。
表2
后文將根據(jù)這個優(yōu)化思路基于Linux這個應(yīng)用廣泛的OS,描述在工程實踐中針對OS的實時性增強,通常的措施有如下一些:
1.根據(jù)業(yè)務(wù)場景需求調(diào)整實時中斷的優(yōu)先級或親和性,確保實時任務(wù)關(guān)注的中斷能夠被及時的響應(yīng),合理設(shè)置中斷的觸發(fā)時機,規(guī)避中斷風暴。
2.提高內(nèi)核時鐘頻率,也就是CONFIG_HZ,增加內(nèi)核時鐘HZ可以顯著的提高任務(wù)響應(yīng)的實時性,本質(zhì)上是通過增加定時中斷,變相增加調(diào)度點,因為Linux內(nèi)核在中斷處理完成時會發(fā)起調(diào)度。同理,取消CONFIG_NO_HZ的配置,也是相同的道理,該配置會減少內(nèi)核無用定時器中斷,降低開銷,進而變相減少調(diào)度點。
3.不論是哪種OS內(nèi)核,在開發(fā)實現(xiàn)時都需要減少鎖的使用,尤其是多個場景或者關(guān)鍵路徑上同時持有一個鎖是需要盡量避免的,可通過大鎖換小鎖或者無鎖設(shè)計來解決。即使必須使用鎖,也需根據(jù)場景選擇開銷最小的方式,如讀寫鎖、互斥鎖、自旋鎖。
4.打開內(nèi)核搶占,大部分OS包括Linux都是支持搶占模式的,用戶可根據(jù)自己的應(yīng)用場景選擇配置不同的搶占模式,在下圖menuconfig中已很明確的說明了每種配置所支持的應(yīng)用場景:強調(diào)吞吐性和可用性的服務(wù)器模式(無搶占點,此模式下內(nèi)核態(tài)代碼完全無法搶占);強調(diào)均衡性能以及用戶響應(yīng)的桌面模式(此模式下通過硬編碼增加了一些自愿搶占點);基于桌面的低延遲增強模式(此模式相對于之前的模式搶占點增加更多)。這三種模式本質(zhì)上都是做一件事,就是在內(nèi)核的各種關(guān)鍵路徑上逐級遞增調(diào)度點。
圖7 Linux內(nèi)核搶占模式
5.Linux RT補丁,打上該補丁后,Linux的搶占模式還會增加兩種,每種模式都包含一些優(yōu)化措施,這些措施本質(zhì)上依然是兩點:減少關(guān)中斷、關(guān)搶占的代碼路徑與增加更多的調(diào)度點。如中斷線程化,該措施會更進一步減少關(guān)中斷執(zhí)行的代碼范圍,把更多的處理邏輯放到中斷線程中去做,線程上下文是可打斷可搶占的;再如通過rt_mutex 重新實現(xiàn)spinlock_t,Linux內(nèi)核的spinlock機制是一種CPU鎖機制,在沒打RT補丁時,一旦調(diào)用該鎖,則禁止中斷或禁止搶占,并持續(xù)占有CPU直到鎖資源就緒,非常影響實時性。重寫spinlock后內(nèi)核中大量使用自旋鎖spinlock的地方變成了可以調(diào)度的點,且不會無意義的空耗CPU。
6.如果不局限實時任務(wù)的處理必須在用戶態(tài),可以在內(nèi)核開發(fā)實時任務(wù),這種方法配合上述其它措施,可大大提高任務(wù)的實時性,因為任務(wù)處于內(nèi)核態(tài),不會有特權(quán)級切換,不會有缺頁異常,上下文切換導(dǎo)致的cachemiss開銷也會小很多,經(jīng)典RTOS所有任務(wù)都運行在一個地址空間,在這一點上有很大優(yōu)勢,即使對于微內(nèi)核OS,在工程實踐中也可以通過將部分關(guān)鍵任務(wù)放在內(nèi)核態(tài)來提高其實時性能如定時器管理任務(wù)。
7.除了上述專門針對實時性的優(yōu)化措施外,還有部分內(nèi)核調(diào)試、安全檢查功能對于實時性影響較大,如lockup檢測機制以及一些調(diào)試功能如ftrace,這些功能單點耗時并不多,但是加在一起也是一個很可觀的開銷。
對于Linux,完成上述優(yōu)化措施后,在不修改內(nèi)核接口以及框架的情況下,通過打補丁的方式能做的優(yōu)化措施也已經(jīng)基本做完了。通常來講,此時Linux任務(wù)的實時性會有一個很明顯的提升,但是是否可以做到硬實時?實踐中對于多數(shù)場景已經(jīng)夠了,但是Linux內(nèi)核功能的豐富性和復(fù)雜性決定了其依然有大量的不確定性,為此就引出了后續(xù)的一些優(yōu)化方案。
8.基于Xenomai或EVL的雙域方案(還有更早的RTLinux),該方案采用雙域,將內(nèi)核分為兩個域,一個功能簡單結(jié)構(gòu)精簡的EVL Core實時域,一個非實時的Linux域,兩個域共同使用一個硬件抽象層,實時域提供一套獨立的接口供上層RT App使用。該方案比較重要的幾個點是:
- Linux域的所有代碼均可被中斷打斷,Linux域的關(guān)中斷代碼被重寫了,實際上不會關(guān)硬件中斷,而僅是置一個標志位
- 所有外設(shè)中斷,均會先交由EVL Core實時域先處理,之后才交給Linux域處理,且不再受Linux域關(guān)中斷影響,因此大大提高中斷處理的及時性
- 運行在實時域的實時任務(wù)的調(diào)度不再依賴Linux域,因為EVL Core實時域的功能簡單,調(diào)度延遲相較于Linux的調(diào)度延遲低很多,可大大提高調(diào)度及時性
- 為保證實時性,RtApp的變成需要使用實時域?qū)S媒涌?,否則可能導(dǎo)致運行域切換影響實時性
圖8 EVL架構(gòu)示意圖
該方案也支持CPU核和內(nèi)存資源的預(yù)先分配,可確保EVL Core實時域獲得確定的CPU核和內(nèi)存資源,該方案在X86平臺上可做到10微秒級的延遲與抖動。把兩個域作為一個整體來看,其核心依然是通過dovetail和evl Core大大降低了中斷延遲與處理的時間以及EVL側(cè)的調(diào)度延遲。
9.如果上述方案依然無法滿足實時性需求,而又確實想使用Linux的生態(tài)和資源,業(yè)界仍然有解決方案,即基于內(nèi)存分區(qū)、CPU核隔離的Linux+RTOS雙系統(tǒng)方案,該方案的相較于EVL的雙域方案更進一步,直接在物理層做了設(shè)備隔離,OS做了軟件隔離,可確保Linux不會影響RTOS側(cè)的實時業(yè)務(wù),如果兩個OS需要通信,既可通過外設(shè)通信,也可通過共享內(nèi)存的機制實現(xiàn)。該方案在工業(yè)控制領(lǐng)域有不少成功的案例,且Linux也可切換為其它操作系統(tǒng)如Windows+RTX。
圖9 Windows+RTX示意圖
措施8、9都是通過不同的方法確保實時任務(wù)和非實時任務(wù)的隔離,且實時任務(wù)由于使用了精簡的RT運行時確保任務(wù)的實時性與確定性。
3.4 實時性與應(yīng)用場景探討
實時和非實時都有其適用的應(yīng)用場景,如對于任務(wù)執(zhí)行時間確定,到達時間確定的周期性任務(wù),采用RMA策略的實時OS能很好的滿足其需求,但是也有部分場景不適合,比如手機、PC機、服務(wù)器等有大量各種類型任務(wù)同時并發(fā)的開放式應(yīng)用場景。在上述這些應(yīng)用場景里,如果系統(tǒng)內(nèi)的任務(wù)全部設(shè)置為基于優(yōu)先級調(diào)度,會是什么情況呢?假設(shè)優(yōu)先級設(shè)置不合理,或者部分應(yīng)用惡意調(diào)高優(yōu)先級頻繁占用CPU資源,會導(dǎo)致一些正常業(yè)務(wù)餓死,UI卡頓,用戶會出現(xiàn)明顯的不適。
在Mixed-critical系統(tǒng)里,既部署有實時任務(wù),也部署有非實時任務(wù),此時需要在保障實時任務(wù)的前提下也確保系統(tǒng)的可用性、吞吐性等,這種場景和需求下并不是所有的實時措施都適合。如在對RtApp進行優(yōu)化時使用的免于干擾機制,不論是核隔離綁定、還是內(nèi)存資源的預(yù)先確定對資源消耗都非常大,會對系統(tǒng)的可用性有影響,在系統(tǒng)資源受限時需要慎重使用;對于雙域方案,則需要對業(yè)務(wù)的部署進行域的劃分,且控制應(yīng)用的編程接口和運行模式,適用于新開發(fā)的應(yīng)用或者是容易移植的場景。在進行實時性優(yōu)化時需要根據(jù)自己的應(yīng)用場景對實時路徑進行分解,明確實施指標并結(jié)合其它系統(tǒng)需求選擇合適的方案。
除此之外實時性不是沒有代價的,高實時性系統(tǒng)保障的是最差場景下的時間約束,而不是平均場景或者最常用場景,實際工程實踐經(jīng)驗是其可能帶來其它場景的性能下降。以下是一些在工程實踐時需要特別注意的點:
1.親和性設(shè)置,不論是中斷的親和性還是任務(wù)的親和性,需要考慮負載的均衡,避免出現(xiàn)“忙死、餓死”等現(xiàn)象尤其是業(yè)務(wù)負荷比較復(fù)雜的mix-critical系統(tǒng),可能會出現(xiàn)除實時性任務(wù)或?qū)崟r中斷能及時響應(yīng)外,其它任務(wù)都不能及時響應(yīng)的問題,最終仍然是不能滿足項目目標的。
2.對于大量使用第三方或者開源組件的項目,mlockall需慎用,避免出現(xiàn)內(nèi)存資源快速耗盡導(dǎo)致OOM的問題,如果系統(tǒng)出現(xiàn)OOM,需要配合調(diào)整相關(guān)實時任務(wù)的優(yōu)先級確保其不會被LMK殺掉。
3.關(guān)于實時任務(wù)的優(yōu)先級,不能設(shè)置成相同的最高99優(yōu)先級,這會導(dǎo)致系統(tǒng)一些實時性要求不高,但是對于可用性非常重要的任務(wù)如Linux里用于各種同步的worker線程餓死,導(dǎo)致系統(tǒng)以其它形式卡死導(dǎo)致不可用,同時優(yōu)先級不是萬能的,優(yōu)先級的設(shè)置必須符合業(yè)務(wù)特征且充分考慮了多個實時任務(wù)間的影響。
4.關(guān)于提高時鐘頻率,關(guān)閉動態(tài)調(diào)頻、休眠等措施,會顯著的提高系統(tǒng)平均功耗,這種情況下需要結(jié)合軟件應(yīng)用場景和硬件平臺的特性進行優(yōu)化,如外掛低功耗MCU做一些低功耗實時任務(wù)的方式解決。
5.關(guān)于Linux的RT補丁,其普適性是有爭議的,尤其是對于大量第三方驅(qū)動的適配并未經(jīng)過充分驗證,盲目打RT補丁可能會導(dǎo)致系統(tǒng)的穩(wěn)定性降低。
6.對于EVL或AMP這種雙域/雙系統(tǒng)方案,其對軟件部署的模型、外設(shè)資源的分配都有要求,需要站在整個系統(tǒng)層面評估方案,避免出現(xiàn)返工。且EVL方案在提高EVL域的實時性的代價是降低了Linux側(cè)的整體實時性與應(yīng)用編程的便捷性。
7.部分優(yōu)化措施是有矛盾點的,如為提高中斷或調(diào)度響應(yīng)的及時性需要增加搶占點和可中斷區(qū)域,但是實時任務(wù)如果想提高實時性和確定性就必須減少系統(tǒng)中斷和調(diào)度的干擾,最好是非搶占,這些措施之間的平衡需要結(jié)合場景和需求考量。
8.實時不等于端到端的快,尤其是多核多任務(wù)的長流程業(yè)務(wù),為提高實時性額外增加的調(diào)度點和中斷勢必會增加系統(tǒng)本身的開銷而降低應(yīng)用可使用CPU的資源,且實時性與極限吞吐性的矛盾從原理上來說是不可調(diào)和的。實時性是一個需求,但不是唯一的需求,需要回到源頭的應(yīng)用場景和客戶價值上來做判斷。
9.最后關(guān)于系統(tǒng)實時性,不僅是OS或者單個實時任務(wù)的事情,而是整個軟件產(chǎn)品里所有有實時訴求的任務(wù)、中間件、OS等各種可能的組合,針對這些具體場景需要結(jié)合系統(tǒng)的可調(diào)度性分析,配合工具進行優(yōu)化和配置,避免頭痛醫(yī)頭、腳痛醫(yī)腳。
四、總結(jié)
本文介紹了實時性的概念,基于一個場景從應(yīng)用和OS的角度分析了影響實時性的各種關(guān)鍵因素,并基于這些因素給出了相應(yīng)的解決方案和思路。在最后章節(jié)探討了這些解決方案的適用性及需要注意的問題。全文總結(jié)如下:
1.影響任務(wù)響應(yīng)的最大因素為中斷延遲和調(diào)度延遲,基于Linux,調(diào)度延遲尤甚
2.提高響應(yīng)速度的關(guān)鍵是降低關(guān)中斷、關(guān)調(diào)度的區(qū)域以及更多的調(diào)度點
3.提高任務(wù)實時性和確定性的關(guān)鍵是排除干擾和基于具體場景的計算資源分配
4.方法可以通用,方案源于需求,細節(jié)決定成敗,沒有包打天下的方案
-
SMP
+關(guān)注
關(guān)注
0文章
78瀏覽量
20285 -
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
605瀏覽量
28618 -
中斷處理
+關(guān)注
關(guān)注
0文章
94瀏覽量
11263 -
嵌入式軟件
+關(guān)注
關(guān)注
4文章
245瀏覽量
27342
發(fā)布評論請先 登錄
嵌入式實時操作系統(tǒng)如何簡化應(yīng)用軟件的設(shè)計
嵌入式系統(tǒng)概述
嵌入式系統(tǒng)概述
嵌入式Linux 實時性分析與實時性改進
通過任務(wù)分割提高嵌入式系統(tǒng)的實時性
嵌入式Linux下的實時性增強方案
嵌入式軟件系統(tǒng)設(shè)計中的正交性分析

嵌入式系統(tǒng)及其實時軟件的開發(fā)
基于Windows CE的嵌入式操作系統(tǒng)實時性分析
基于Petri網(wǎng)的嵌入式軟件組件的實時性分析

慕課嵌入式系統(tǒng)(第六章.嵌入式軟件系統(tǒng)概述)

評論