實時性迷思(1) —— “快是優點麼?”

【序】


不知道你發現沒有,平時我們討論嵌入式軟件開發時總繞不開與實時性(Real Time)相關的話題。相信不少朋友和我一樣是通過實時性操作系統(Real Time Operating SystemRTOS)第一次接觸到實時性概念的——我記得那還是大學時代、參加機器人競賽的時候。工作以後自信地以爲加深了不少對實時性的本質認識——現在看來其實還未摸到門道。就這樣渾渾噩噩一直到畢業後的第八年,因爲工作變動的原因,我被迫要在一週內要做一個實時性原理相關的研究報告,也就在那時,我體會到了瘋狂練功走火入魔的感覺:走路在思考、吃飯在看資料、頭一直髮燒一樣的微微發熱、甚至連睡覺都在夢中推演模型——頭髮一把一把的掉,幸好有截稿時間,否則真的要禿了。

也就是經過那一次,我突然發現自己之前對實時性的認知可謂徒有其表,甚至從未做對實時性模型本身的定量分析——所幸,那次研究報告如期交付,工作變動也如願以償。然而,3年後我發現“我又雙天真了”——那是有一次,我正跟人討論嵌入式基本範式,就突然一個瞬間,腦海中原本毫不相關的一些模型猛地被聯繫到了一起(音效請腦補):

我甚至本能的立即意識到:之前自己在某篇文章中“言之鑿鑿”的推論過程其實存在巨大漏洞——當然,那本書從未出版過,而且會閒到對我進行深究的人估計也沒有幾個。

今天,即便我非常確信——在前方至少還有幾道數學的深谷阻礙着我觸碰“實時性”的聖盃——然而我並不是計算機科學家,現有結論對我來說已經足夠裝逼回頭看來,根據我的經驗以及與朋友討論的結果,大致認爲大部分人對實時性的認知過程通常會分以下幾個階段:

  • Lv1:“實時性” = “越快越好”,認爲用好中斷是保證實時性的關鍵;這類朋友通常最擅長的是裸機下的“前後臺系統”;

  • Lv2:“實時性” = RTOS,認爲選一個好的RTOS,或者會用RTOS就可以保證實時性;這一階段的朋友對RTOS充滿了好奇,以編寫自己的RTOS爲“ 終(zhong)極(er)目標”;

  • Lv3:“實時性” = 任務拆分,這一階段已經能正確的理解實時性窗口的概念,意識到實時性並不意味着越快越好,但也認爲“在可能的情況下”“快一點響應事件沒啥壞處”;這一階段的朋友可能已經可以在裸機和RTOS之間自由的反覆橫跳,無論是裸機下的狀態機還是RTOS下的線程都已瞭如指掌、任務間通信更是遊刃有餘;

  • Lv4:這一階段開始思考實時性模型的特點,並逐漸意識到模型本身其實隱含了足以顛覆過往所有關於實時性認知的祕密;到達這一階段的朋友通常覺得沒必要、也沒心思繼續思考實時性更本質的數學意義——因爲此時獲得的結論已經足夠了應付幾乎所有的工程開發了。順便說一下,我就在這裏

  • Lv5:到了這個階段,不僅腦洞大開、戰鬥力驚人、估計打針也沒法阻止你抓破脖子了吧——以上只是暴露年齡的玩笑,但肯定可以水幾篇SCI論文了……

在理解了實時性的模型以後,(本能的排除了自己比較笨這個可能性,然後意識到:其實這一過程完全沒必要如此漫長和曲折——很多結論和道理是如此簡單——不僅書本上有,而且解釋和學習起來都不費什麼力氣。可能這就是“撓破頭”想通某個道理之後,回頭再看時忍不住要“苦笑”時的感受吧。

按照約定,爲了將經驗和知識分享給大家,從本文開始,我將以幾篇文章的篇幅:從基礎模型開始,由淺入深、由理論到實踐,推演關於實時性的幾個重要結論——從而直接跳躍到Lv4的認知階段。如果你看了這個系列後有什麼話想說的、想問的,還請在評論區寫下您的留言。求評論、求轉發、求收藏

【擊碎 “唯快不破” 的神話】

圖1展示了一個標準的實時性模型:

  • 基於物理世界客觀法則的限制,很多應用在制定需求說明的時候,從某一個事件發生的時刻計算,會規定一個死線(Dead Line),即:一旦事件發生了,如果不在這個死線之前完成整個對事件的處理,就視作失敗;

  • 這裏,從事件發生到死線這段時間長度,習慣上稱爲實時性窗口。當事件發生時,只有在死線內任意時刻完成了對事件的處理,才能稱爲實時性得到了滿足

  • 容易注意到,處理事件的過程也需要消耗時間——一般稱爲事件處理時間

圖1 實時性基本模型

考慮一個有趣的問題:對一個實時性任務來說,實時性窗口內的時間,其價值是一樣的麼?換句話說,橫豎處理事件消耗的時間是不變的,早點做遲點做都是做,有什麼區別麼?

圖2 實時性窗口內不同時間段完成事件響應

對比圖2所示的三種情況,可以很清楚的得出結論:理論上,從滿足實時性的角度出發,在時間窗口內任意時段完成對事件的處理都滿足實時性要求;早做沒有任何額外的好處,“踩着上課鈴到校”也沒有任何懲罰——簡單說就是早做遲做無所謂

你說“我不管,我不管”,既然什麼時候做都一樣爲什麼不能“儘早做”?你也說了儘早做沒啥不好”,“中斷來了,服務程序執行了,我想讓它遲點執行也做不到啊?

爲了回答這個問題,我們不講大道理,先看一個常見的例子:

  • 超級循環裏有三個任務A、B和C;

void main(void)
{
    ...
    while(1) {
        task_a();
        task_b();
        task_c();
    }
}
  • 每個任務都使用輪詢的方式在等待一個來自芯片外界的事件發生(先不考慮存在中斷的情況);

  • 當一個任務函數被執行時會檢查對應的事件是否已經發生,如果確實已經發生,則執行後續的處理;反之則立即退出任務函數——釋放處理器;

  • A、B、C三個事件的實時性窗口分別爲10ms6ms4ms;處理三個事件的處理程序分別需要4ms3ms0.4ms。如圖3所示:

圖3 三個事件的實時性窗口和事件處理時間示意圖

  • 需要強調的是,task_a()task_b()task_c()三個函數的策略本質上都是一樣的——“一旦檢測到事件立即處理,絕不遲延”!

基於上述事實,容易發現:假如某一時刻,A、B、C三個函數都處於觸發狀態(等待處理的狀態),而超級循環恰巧進入task_a()執行——這種情況其實比想象中容易發生,比如從task_a()退出到task_c()執行完成期間,事件A觸發了;從task_b()退出到task_c()執行完成期間,事件B觸發了;在task_c退出()之後恰巧事件C又觸發了……此時,任務A會立即響應,消耗4ms的時間來完成事件處理;當從task_a()函數退出時,剩餘給task_b()的時間窗口只有2ms6ms-4ms),而事件B的處理函數需要3ms——顯然事件B的實時性是無法得到保證的——當然事件C已經死得透透了……

圖 4 “越快處理越好” 導致其它任務無法滿足實時性要求

通過上面的例子,我們知道“越快處理越好”是值得反思的——至少會存在情況導致系統在某些時刻無法滿足實時性要求;那麼從模型上來說,如何理解這一現象呢?

讓我們重新來看圖1所示的模型:

實際上,如果單純從一個實時性任務自身出發來看,的確在實時性窗口內,任意時間完成事件的處理都是一樣的;然而,通過前面的舉例我們其實可以發現,當一個系統中存在多個實時性任務時,雖然一個實時性窗口內的任意時間對任務自己都是等價的,但越靠前的時間對“別人”來說是越寶貴的:

  • 當你使用“越快越好”策略時,你不會有額外的收益,而實際上是走了別人的路,讓人無路可走——典型的損人不利己

  • 當你在別人需要的時候,在自己實時性得到保證的前提下,儘可能讓出對你沒有額外價值的靠前的時間,實際上是一種“利他主義”

  • 當所有的任務都採用這種利他策略時,就變成了“人人爲我,我爲人人”的合作策略——這種情況下,如果數學證明整個系統一定存在一個方案來滿足所有任務的實時性需求,那麼利他策略一定能找到這樣的解決方案。

圖 5 一種可能的解決方案(不是唯一)

作爲一個系統開發者,我們顯然是需要從全局考慮的,因此完全沒有必要從單個實時性任務的自私視角來看問題,因此結論就變得更爲直接:實時性窗口內越靠前的時間價值越高,從總體上來看“單純”越快越好的策略對實時性是有害的

既然單純的“越快越好”不可取,且“實時性窗口內”越靠前的時間越有價值,是否意味着,其實“越靠後越好呢”

爲了驗證另外一個極端“越慢越好(越靠後越好)”是否是正確的,我們不妨以同樣的例子來推演一下,僅僅更新task_a()task_b()task_c()的執行策略:從“越快越好”變爲“越慢越好”——這實際上意味着:

  • 每一個事件處理任務都清楚的知道“距離事件發生已經過去了多長時間”;

  • 爲了做到“卡着上課鈴進教室”,不到最後時刻,絕對不執行任務處理。

根據這一算法,我們推演得到以下的尷尬情形:

圖 6 過於謙讓的後果……

不妨分析下過程:首先,task_a()執行,在瞭解到距離自己的最後時刻還有6ms的實時後毅然的決定把寶貴的時間留給他人;於是,CPU來到了下一個任務函數,基於類似的原因,task_b()也擺擺手……最終第一輪三個任務都決定再等一等……

如此謙讓(浪費)了3ms以後,任務B終於決定下場——在執行了3ms任務處理後,成功的將隨後的任務C逼上了絕路……隨着A的淪陷,大型翻車現場成就達成……

從結論上看,另外一個極端“越慢越好”也是走不通的。那麼究竟如何才能從模型分析的角度出發得出一個令人信服的、容易理解的、滿足所有任務實時性需求的方法呢?關於這一點,我們下次再聊。

【小結】


從系統全局來看,實時性窗口內的時間越靠前越有價值,應該儘可能留給別的更緊急的任務來使用。事件發生時“越快處理越好”的策略直接佔用了它人的“生命線”——當所有的任務都試圖“損人不利己”時,那麼整個系統沒有一個任務是可以保證自己的實時性不被它人破壞的。從結論上看簡單的“越快越好”策略在實時性系統中是不允許的

1.7位專家彙集| 不可不聽的線上嵌入式技術講座在這裏!

2.樹莓派 4:全新的背後,依然是優秀的表現嗎?

3.對國內半導體代工廠“保留無限追溯”,裏面有誤讀!

4.既想馬兒一直跑又想馬兒不吃草,這款Wi-Fi 芯片幫你實現了!

5.單片機裏面的CPU使用率是什麼鬼?

6.學Linux驅動:應先了解總線驅動模型!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章