百度Apollo 3.5是如何設計Cyber RT計算框架的?
自百度Apollo自動駕駛平臺開源以來,已快速迭代至 3.5 版本,程式碼行數超過 39 萬行,合作伙伴超過 130 家,吸引了來自 97 個國家的超 15000 名開發者。無疑,Apollo 是目前世界範圍內最活躍的自動駕駛開放平臺之一。
最新發布的 Apollo 3.5 總體架構從上到下仍分為四層,最底層為車輛平臺,自動駕駛汽車需要對車輛進行線控改造,使得車載大腦可以通過電訊號來控制車輛的執行器;往上一層是硬體平臺,包括計算單元、感測器以及 V2X 相關接收裝置等。再上一層是軟體平臺,主要包括作業系統、中介軟體、演算法模組等。最頂層的是雲端服務,主要包括地圖、OTA 服務升級、資料平臺、語音互動等方面。
此次釋出的Apollo 3.5,解鎖了Apollo 在複雜城市道路中的自動駕駛能力,並開源了 Cyber RT 計算框架、V2X 車路協同方案以及硬體平臺的一些能力。
隨著自動駕駛技術不斷髮展,Apollo 已經從研發走向量產產品落地。作為 Apollo 開源軟體平臺的一部分,Apollo Cyber RT 處於底層的實時作業系統(RTOS) 和演算法模組之間,那麼如何能夠在保證高吞吐的情況下,又能低延遲的實時響應上層任務,並保證整個系統確定性的運轉,1 月 24 日,在 CSDN 平臺上舉辦的 Apollo 開發者社群公開課上,百度主任架構師王柏生就 Cyber RT 的設計思考,總體架構以及關鍵模組相關細節同開發者做了分享。
從 ROS 系統說起
Apollo 最初用的中介軟體是 ROS(機器人作業系統),概括來說,ROS 系統主要包含三方面:
第一是通訊系統,ROS 是個分散式的鬆耦合系統,演算法模組是以獨立的程式形式存在的,也就是我們常說的 Node。ROS 基於 Socket 實現了pub/sub 的通訊方式,不同的演算法節點(node)之間通過 pub/sub 的傳送/接收訊息。
第二是 Framework&Tools (框架和工具),開發者可以基於 ROS 提供的 Client Library 和通訊層,方便的收發訊息。開發者只需要關注訊息處理相關的演算法,而至於演算法何時被呼叫,全部由框架來處理。
第三是生態系統,從社群內,開發者可以很方便地尋找到很多現成的「感測器驅動」和「演算法實現」等進行參考。
隨著自動駕駛的發展,不少開發者,包括 Apollo 平臺,把 ROS 應用於自動駕駛系統,畢竟自動駕駛汽車也相當於一個大的機器人。但是我們在實踐中也遇到了很多挑戰:
首先,ROS 中的演算法模組是以獨立的程式形式存在的,那麼這些程式之間應該以什麼樣的順序去執行?實際上,Linux 本身是一個通用系統,核心中的排程器對上面的演算法業務邏輯並不清楚,它只是在儘量滿足公平的情況下讓大家都得到排程。所以,ROS Node 執行順序並無任何邏輯。
但本質上自動駕駛是一個專用系統,任務應該按照一定的業務邏輯執行。那麼是在 ROS 層加一個 Node,由其來同步各個演算法任務的執行,還是在Linux 核心中實現新的排程策略,使其結合演算法業務邏輯進行排程?前者的開銷,後者的遷移性,都是需要思考的問題。
其次,ROS 是一個分散式的系統。既然是分散式,就要有通訊的開銷。即使在同一個物理節點上,依然存在著通訊的開銷。所以 Apollo 前期曾經使用共享記憶體去降低 ROS 原生的基於 Socket 通訊的開銷。ROS 2 也在使用 DDS 解決通訊方面的實時性。ROS 也支援 Nodelet 模式,這可以去掉程式間通訊的開銷,但是排程的挑戰依然存在。
第三,除了排程的不確定性,ROS 系統中還存在其他很多不確定的地方,比如記憶體的動態申請。
Cyber RT 的執行流程
演算法模組通過有向無環圖(DAG),配置任務間的邏輯關係。對於每個演算法,也有其優先順序、執行時間、使用資源等方面的配置。系統啟動時,結合DAG、排程配置等,建立相應的 任務,從框架內部來講,就是協程,排程器把任務放到各個 Processor 的佇列中。然後,由 Sensor 輸入的資料,驅動整個系統運轉。
Cyber RT 架構
基本上,Cyber RT 包括如下軟體模組:
最下面一層是基礎庫,為了高效,Cyber RT 實現了自己的基礎庫。比如我們實現了 Lock-Free 的物件池,實現了 Lock-Free 的佇列,隨著成熟,會陸續開放更多。除了框架自身外,將來也會逐漸應用於演算法模組。除了效率原因為,也希望 Cyber RT 減少依賴。
再往上是通訊相關的,包括服務發現,還有 Publish-Subscribe 通訊機制。 Cyber RT 也支援跨程式、跨機通訊,上層業務邏輯無需關心,通訊層會根據演算法模組的部署,自動選擇相應通訊機制。
通訊層之上是 資料快取/融合層,多路感測器之間資料需要融合,而且演算法可能需要快取一定的資料。比如典型的模擬應用,不同演算法模組之間需要有一個資料橋樑,資料層起到了這個模組間通訊的橋樑的作用。
再往上是計算模型,計算模型包括剛才前面提到的排程和任務,後面我們會詳細討論。
計算模型之上是為開發者提供的介面。Cyber RT為開發者提供了Component 類,開發者的演算法業務模組只需要繼承該類,實現其中的 Proc 介面即可。該介面類似於 ROS 中的 Callback,訊息通過引數的方式傳遞,使用者只要在Proc中實現演算法、訊息處理相關的邏輯。Cyber RT 也基於協程,為開發者提供了平行計算相關的介面。
Cyber RT 也為開發者提供了開發除錯、錄製回放等工具,未來還會開放效能除錯工具。
從核心空間到使用者空間
ROS 的主要挑戰之一是沒有排程,為了解決 ROS 遇到的問題,Cyber RT 的核心設計將排程、任務從核心空間搬到了使用者空間。排程可以和演算法業務邏輯緊密結合。
從 Cyber RT 角度,OS 的 Native thread 相當於物理 CPU。
在 OS 中,是核心中的排程器負責排程任務(程式、執行緒…)到物理 CPU 上執行。而在 Cyber RT 中,Cyber RT 中的排程器排程協程(Coroutine)在 Native Thread 上有序執行。
編排排程策略
任務編排策略是 Cyber RT 開源的主要策略之一。每個 Processor (Native Thread) 一個任務佇列,由排程器編排佇列中的任務。任務在哪個 CPU 上執行?任務之間是否需要相鄰執行?哪些先執行?哪些後執行?都由排程器統一排程,任務基於協程實現。在任務阻塞時,快速讓出 CPU。
每個物理 CPU 上除執行1個 normal 級別的 thread 外,執行著另外 1+ 個高優先順序的 thread,基於此,實現使用者空間的高優先順序的任務搶佔執行。比如,之前去 GPU 執行的演算法,在 GPU 上完成執行返回後,應該儘快的得到執行。
這種排程策略,很好的結合了業務邏輯、資料共享和算力的平衡。並且任務不會在不同 CPU 上隨機的排程來排程去,具有非常好的 Cache 友好性。
經典排程策略
任務編排策略,不僅需要對業務邏輯的深度理解,也需要結合計算機的算力等綜合考慮。因此,Cyber RT 也提供了類似經典執行緒池模式的排程演算法,這種模式幾乎不存在配置的代價。對此,Cyber RT 也做了一些改進,比如為了減小鎖的瓶頸,任務是多佇列的。任務佇列也支援優先順序,後續還會支援分組,通過組控制演算法對資源的使用。
演算法任務的載體—協程
Cyber RT 使用了協程作為演算法任務的載體。協程之於執行緒,就類似於執行緒之於物理 CPU,由 Cyber RT 中的排程器負責在各個執行緒之上週而復始,切換排程協程。為了演算法模組在其他協處理器執行計算時,可以讓出Processor(Native Thread),並在完成之後,回來時可以再次執行,Cyber RT採用了有狀態的協程。
那麼 Cyber RT 為什麼採用協程呢?除了協程的切換非常快之外,排程的確定性是另外一個重要的原因。舉個典型的例子,假設用 native thread 去執行一個任務,當任務因為去 GPU 等加速器運算時,或者因為資源原因被Block 時,在 thread 就緒時,什麼時候排程上來其實是一個非確定的過程,完全依賴於作業系統以及其上任務的情況。
Cyber RT也支援跨程式、跨機通訊
實際部署中,也存在著比如某個工具需要執行在獨立的程式,安全系統部署在另外的節點。因此,Cyber RT 也支援跨程式、跨機通訊。上層業務邏輯無需關心,通訊層會根據演算法模組的部署,自動選擇相應通訊機制。
以上就是本次直播分享的內容。非常感謝大家的參加!也歡迎大家提出問題,進行交流。更多 Apollo 相關的技術乾貨也可以繼續關注 Apollo 開發者社群每月的課程分享,也可以在 Apollo GitHub(https://github.com/ApolloAuto/apollo)上提出技術問題與我們互動,期待大家的溝通交流!
相關文章
- 【Apollo】(2)--- Apollo架構設計架構
- 配置中心的設計-nacos vs apollo
- 詳解apollo的設計與使用
- Apollo 4 客戶端 SDK 設計客戶端
- Go 語言是如何計算 len() 的?Go
- 10 早期計算機如何程式設計計算機程式設計
- 我是如何使計算提速>150倍的
- 百度的評論系統是怎麼設計的?
- 攜程開源專案——Apollo的設計與實現
- 《自然》:如何更有效學習計算機程式設計?計算機程式設計
- 如何設計一個流計算基準測試?
- 如何檢查你的計算機使用的是 UEFI 還是 BIOS計算機iOS
- 程式設計師的計算機配置程式設計師計算機
- RPC 框架設計RPC框架
- 計算機學院的老師實際程式設計能力如何?計算機程式設計
- “雲端計算”工作是如何讓企業受益的?
- 好程式設計師雲端計算培訓分享雲端計算中SOA是什麼?程式設計師
- Base58編碼的長度是如何計算的?
- 我是如何設計後臺框架裡那些錦上添花的動畫效果框架動畫
- 你是如何看待男程式設計師的?程式設計師
- 程式設計師你是如何降低NPE的?程式設計師
- 那些程式設計高手是如何練成的?程式設計
- 分庫分表的框架如何設計自動路由框架路由
- 好程式設計師雲端計算培訓分享雲端計算中微服務是什麼?程式設計師微服務
- 我是如何提高自己的「程式設計能力」的?程式設計
- grafana 的主體架構是如何設計的?Grafana架構
- ArkUI,更高效的框架設計UI框架
- 你真的知道計算機是如何進行減法運算的嗎?計算機
- 《暗黑3》設計師是如何評價自己遊戲中陷阱的設計?遊戲
- 設計方案系列-如何看待前端框架選型 ?前端框架
- UC Berkeley EECS是如何培養計算機學生的計算機
- 外甥女問我計算機是如何組成的?計算機
- 【Python】我是如何使計算時間提速25.6倍的Python
- 我是如何把計算機網路考了100分的?計算機網路
- Apache Flink,流計算?不僅僅是流計算!Apache
- 【程式設計框架】Android可配置的ScrollView框架程式設計框架AndroidView
- 2021-2-17:Java HashMap 的中 key 的雜湊值是如何計算的,為何這麼計算?JavaHashMap
- 什麼是網頁設計的"原子設計”?網頁