技術文檔丨Cyber RT車載系統CPU資源調度和數據與協程任務驅動模型

本文做者:Apollo開發者社區javascript

近日,隨着Apollo5.0的升級,Cyber RT再次進行了更新,主要包括三方面的新支持:ARM架構的處理器支持、Python API的全面支持、Cyber RT API文檔站的支持。java

 

Apollo Cyber RT計算框架的核心功能是計算任務調度和提供底層通訊服務,解決了此前ROS框架存在的難題,更加適用於自動駕駛領域。算法

 

在當前的無人車載運行環境中,爲了提升任務並行性,算法模塊會建立大量的異步任務,若是任由異步任務搶佔CPU資源,會致使以下問題:架構

 

  1. 傳統異步任務採用OS Thread實現,由OS Kernel進行調度,用戶空間沒法對這些任務上核順序及執行週期性進行控制,無人車載計算任務實時性沒法獲得保證。框架

  2. OS Kernel採用時間分片算法對這些異步任務進行調度,當異步任務增多時,Context Switch開銷會被放大。異步

  3. 大量不相關的異步任務相互搶佔CPU資源,形成Cache MissCache Bouncing開銷this

 

  如下,ENJOY  spa

 

Cyber RT框架

 

在Cyber RT框架中,調度器將算法異步任務從OS Thread轉爲Cyber RT Task(協程)在用戶空間進行CPU資源調度,同時封裝了OS Kernel CPU親和性及調度策略配置接口,控制OS Thread及OS Process在OS Kernel中的CPU資源調度。造成完備的無人車載系統CPU計算資源管理方案,軟件結構以下:操作系統

 

▲Cyber RT框架架構圖線程

 

經過架構圖能夠清晰看到,在Cyber RT框架下:

 

  1. Algorithm Layer共有三種異步任務,分別爲OS Process(操做系統進程)OS Thread(操做系統線程)Cyber RT Task(用戶空間協程)

  2. Cyber RT Scheduler介於OS&&Hardware與Algorithm Layer之間,負責Cyber RT Task CPU資源調度,以及經過配置OS Process、OS Thread CPU親和性及Kernel調度策略,來控制它們在OS Kernel中的CPU資源調度。

  3. 大量異步任務由OS Thread轉爲Cyber RT Task,即協程,由Cyber RT調度器在用戶空間統一調度,因爲協程上下文切換徹底由Cyber RT調度器控制,Cyber RT Task執行順序、切換徹底由Cyber RT調度器決定,無需通過OS Kernel,算法層異步任務實時性週期性獲得保證。同時,OS Thread 數量減小,無人車系統中的Context Switch開銷大大下降。

  4. 不一樣OS Process間經過Cyber RT Scheduler控制其CPU親和性,在CPU資源上相互隔離,大大減小了Cache Miss及Cache Bouncing開銷。

  5. OS Thread繼承OS Process的CPU親和性,不相關的OS Thread在CPU資源上自然相互隔離,大大減小了Cache Miss及Cache Bouncing開銷。下面,咱們就基於車載任務拓撲樣例,來闡述如何實施車載CPU資源控制方案。

 

車載CPU資源配置實施方案

 

車載任務拓撲樣例

 

▲模擬任務關係圖

 

咱們仿照車載計算任務,作了如上模擬任務關係圖,它至關於咱們架構圖中的算法層,是咱們的調度目標,簡單闡述以下:

 

  1. DriverPerceptionPNC分別對應於無人車的驅動、感知、規劃控制模塊,不一樣模塊之間經過消息傳遞連接

  2. Driver與Perception模塊運行在OS Process1,PNC運行在OS Process2 。

  3. 不一樣模塊均包含Cyber RT Task(用橙框標註),並建立了異步OS Thread(用藍框標註)。

 

硬件配置

 

CPU結構:4物理核UMA構架。

 

內存:16G。

 

在接下來的配置中,指望達成以下結果:

 

  1. OS  Process1與OS  Prcess2分別各自佔用一半CPU資源。

  2. 兩個進程中的Cyber RT調度器分別配置CPU親和性以及Kernel調度策略。

  3. Cyber RT Task根據關聯關係分別設置優先級調度策略

  4. 給出OS Thread綁核樣例。

 

配置文件命名

 

Cyber RT調度器在程序啓動時,會默認按照process_name字段,查找加載調度器配置。在這裏,咱們命名OS Process1爲"compute3d_sched",命名OS Process2爲"control_planning_sched",下面論述中,咱們以相應進程名來表示兩個進程,以便區分。

 

調度器配置文件建立規則爲"進程名+.conf",樣例以下:

 

1$touch compute3d_sched.conf
2$touch control_planning_sched.conf

注:process_name字段,須要在launch文件中配置,而後由mainboard加載dag文件時,經過-p參數傳入。譬如,咱們有一個planning.dag,咱們可使  用"mainboard -d planning.dag -p control_planning_sched"來運行dag,同時指定process_name。

 

OS Process配置

 

咱們將前兩個物理核分配給compute3d_sched,後兩個物理核分配給control_planning_sched,配置以下:

 

compute3d_sched.conf:

 

1scheduler_conf {
2process_level_cpuset: "0-1, 4-5" #OS ProcessCPU0415
3}

 

control_planning_sched.conf:

 

1scheduler_conf {
2process_level_cpuset: "2-3, 6-7" #OS ProcessCPU2637
3}

 

調度器配置

 

Cyber RT 調度器有兩種調度策略,分別爲Choreo與Classic,Choreo策略是Cyber RT下無人車專屬調度,它強調任務執行週期性以及實時性。在咱們的樣例中,咱們以Choreo策略配置爲例講解。

 

Classic做爲經典調度,不在本篇文章中作過多介紹,讀者能夠在apollo/cyber/conf的樣例配置中找到Classic配置樣本。

 

使用樣例

 

compute3d_sched.conf:
 
1scheduler_conf {
 2policy: "choreography"
 3process_level_cpuset: "0-1, 4-5"
 4choreography_conf {
 5choreography_processor_num: 4 #Choreo
 6choreography_affinity: "1to1" #CPU1to1, CPUrangeCPU
 7choreography_cpuset: "0-14-5" #cpu
 8choreography_processor_policy: "SCHED_OTHER" #SCHED_FIFOSCHED_RR
 9SCHED_OTHERThreadkernel
10choreography_processor_prio: -10 #ThreadkernelLinux
11pool_processor_num: 8 #pooltaskpool
12}
13}

 

control_planning_sched.conf:

 

1scheduler_conf {
 2policy: "choreography"
 3process_level_cpuset: "2-3, 6-7"
 4choreography_conf {
 5choreography_processor_num: 4 #Choreo
 6choreography_affinity: "1to1" #CPU1to1, CPUrangeCPU
 7choreography_cpuset: "2-3, 6-7" #cpu
 8choreography_processor_policy: "SCHED_OTHER" #SCHED_FIFOSCHED_RR
 9SCHED_OTHERThreadkernel
10choreography_processor_prio: -10 #ThreadkernelLinux
11pool_processor_num: 8 #pooltaskpool
12}
13}

 

Cyber RT Task配置

 

在Cyber RT下,咱們建議按照以下原則設定Task調度配置: 

 

  1. 相同鏈路Task儘可能綁定到相同Processor上,提升Cache locality

  2. 相同鏈路Task,子節點Task優先級高於父節點Task,好比感知模塊中Recognition優先級要高於Segmentation。

  3. 處於同Processor上Task們,總處理時延最大值不能高於鏈路處理週期,保證傳感器消息處理實時性。在本案例中,爲了簡潔性,暫不考慮該場景。

  4. 暫時不能進行綁定Processor的Task能夠設定優先級而後放入到pool中 。

 

這種配置策略下,越是對整車運行狀態影響大的任務每每會更早獲得CPU資源,同時,同鏈路上任務週期性也獲得有效保證。這在百度無人車系統上已獲得充分驗證了。固然,讀者能夠按照本身對無人車任務的理解去配置任務優先級。

 

使用樣例

 

compute3d_sched.conf:

 

1scheduler_conf {
 2policy: "choreography"
 3process_level_cpuset: "2-3, 6-7"
 4choreography_conf {
 5choreography_processor_num: 4 #Choreo
 6choreography_affinity: "1to1" #CPU1to1, CPUrangeCPU
 7choreography_cpuset: "0-14-5" #cpu
 8choreography_processor_policy: "SCHED_OTHER" #SCHED_FIFOSCHED_RR
 9SCHED_OTHERThreadkernel
10choreography_processor_prio: -10 #ThreadkernelLinux
11pool_processor_num: 8 #poolprocessortask
12tasks: [
13{
14name: "Segmentation" #Task
15prior: 4 #TaskDAGTask
16processor: 0 #TaskProcessorTaskATask
17processor
18}, {
19name: "Recognition"
20prior: 3
21processor: 0
22}, {
23name: "Localization" 
24processor: 1
25}, {
26name: "Gnss" 
27prior: 3 
28}, {
29name: "Lidar"
30prior: 1
31}, {
32name: "Camera"
33prior: 2
34}
35]
36}
37}
 
control_planning_sched.conf:
 
1scheduler_conf {
 2policy: "choreography"
 3process_level_cpuset: "2-3, 6-7"
 4choreography_conf {
 5choreography_processor_num: 4 #Choreo
 6choreography_affinity: "1to1" #CPU1to1, CPUrangeCPU
 7choreography_cpuset: "2-36-7" #cpu
 8choreography_processor_policy: "SCHED_OTHER" #SCHED_FIFOSCHED_RR
 9SCHED_OTHERThreadkernel
10choreography_processor_prio: -10 #ThreadkernelLinux
11pool_processor_num: 8 #poolprocessortaskpool
12tasks: [
13{
14name: "Canbus" #Task
15prior: 4 #TaskDAGTask
16processor: 0 #TaskProcessorTaskATask
17processor
18}, {
19name: "Control"
20prior: 3
21processor: 0
22}, {
23name: "Planning" 
24processor: 0
25}
26]
27}
28}
 
 

OS Thread配置

 

原則上講,Cyber RT指望算法模塊中全部的異步任務均使用Cyber RT Task(協程),這樣Cyber RT調度器就能夠在用戶空間對計算任務進行統一調度, 但由於當前無人車仍處於快速迭代的階段,算法模塊的實現或引入第三方庫過程當中,老是會使用OS Thread。

 

所以,Cyber RT調度器在架構設計上,提供了OS Thread的CPU親和性及Kernel調度策略配置入口,用來兼容當前現狀。

 

使用樣例

 

咱們以Driver模塊中建立1個線程爲例進行講解,OS Thread綁定過程須要以下兩個步驟:

 

第一步,在調度器配置中,加入Thread名稱以及CPU親和性配置。

 

1scheduler_conf {
 2policy: "choreography"
 3threads: [
 4{
 5name: "ThreadA" #
 6cpuset: "0, 4" #cpu
 7policy: "SCHED_OTHER" #SCHED_FIFOSCHED_RRSCHED_OTHERThreadkernel
 8prio: -10 #ThreadOS kernelLinux
 9}
10]
11}

 

 

第二步,將Thread句柄以及Thread Name傳入到Cyber Scheduler,完成線程優先級配置。

 

1std::thread thread = std::thread(&ClassA::Run, this);
2std::string name = "ThreadA";
3auto sched = scheduler::Instance();
4sched->SerInnerThreadAttr(thread, name);

 

Cyber RT數據與協程任務驅動模型

 

▲Cyber RT數據與協程任務驅動模型流程圖

 

總結

 

本篇文章,咱們介紹了Cyber RT框架在用戶空間對算法層異步任務OS ProcessOS ThreadCyberRT Task的CPU計算資源的總體統一控制以及數據與協程任務驅動模型的操做流程。相關詳細的示例配置以及實車的調度器配置,咱們均可以在apollo/cyber/conf目錄下找到。須要進一步說明的是,Cyber RT對車載環境中的系統中斷、 kwork的CPU計算資源控制也作了考慮,但這部分須要Root權限,被放到了咱們定製的Base OS中,故而沒有在當前文章中作出介紹。

原文連接地址:https://developer.baidu.com/topic/show/290451

相關文章
相關標籤/搜索