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