本文做者:Apollo开发者社区javascript
近日,随着Apollo5.0的升级,Cyber RT再次进行了更新,主要包括三方面的新支持:ARM架构的处理器支持、Python API的全面支持、Cyber RT API文档站的支持。java
Apollo Cyber RT计算框架的核心功能是计算任务调度和提供底层通讯服务,解决了此前ROS框架存在的难题,更加适用于自动驾驶领域。算法
在当前的无人车载运行环境中,为了提升任务并行性,算法模块会建立大量的异步任务,若是任由异步任务抢占CPU资源,会致使以下问题:架构
传统异步任务采用OS Thread实现,由OS Kernel进行调度,用户空间没法对这些任务上核顺序及执行周期性进行控制,无人车载计算任务实时性没法获得保证。框架
OS Kernel采用时间分片算法对这些异步任务进行调度,当异步任务增多时,Context Switch开销会被放大。异步
大量不相关的异步任务相互抢占CPU资源,形成Cache Miss、Cache Bouncing开销。this
如下,ENJOY spa
在Cyber RT框架中,调度器将算法异步任务从OS Thread转为Cyber RT Task(协程)在用户空间进行CPU资源调度,同时封装了OS Kernel CPU亲和性及调度策略配置接口,控制OS Thread及OS Process在OS Kernel中的CPU资源调度。造成完备的无人车载系统CPU计算资源管理方案,软件结构以下:操作系统
▲Cyber RT框架架构图线程
经过架构图能够清晰看到,在Cyber RT框架下:
Algorithm Layer共有三种异步任务,分别为OS Process(操做系统进程)、OS Thread(操做系统线程)、Cyber RT Task(用户空间协程)。
Cyber RT Scheduler介于OS&&Hardware与Algorithm Layer之间,负责Cyber RT Task CPU资源调度,以及经过配置OS Process、OS Thread CPU亲和性及Kernel调度策略,来控制它们在OS Kernel中的CPU资源调度。
大量异步任务由OS Thread转为Cyber RT Task,即协程,由Cyber RT调度器在用户空间统一调度,因为协程上下文切换彻底由Cyber RT调度器控制,Cyber RT Task执行顺序、切换彻底由Cyber RT调度器决定,无需通过OS Kernel,算法层异步任务实时性、周期性获得保证。同时,OS Thread 数量减小,无人车系统中的Context Switch开销大大下降。
不一样OS Process间经过Cyber RT Scheduler控制其CPU亲和性,在CPU资源上相互隔离,大大减小了Cache Miss及Cache Bouncing开销。
OS Thread继承OS Process的CPU亲和性,不相关的OS Thread在CPU资源上自然相互隔离,大大减小了Cache Miss及Cache Bouncing开销。下面,咱们就基于车载任务拓扑样例,来阐述如何实施车载CPU资源控制方案。
▲模拟任务关系图
咱们仿照车载计算任务,作了如上模拟任务关系图,它至关于咱们架构图中的算法层,是咱们的调度目标,简单阐述以下:
Driver、Perception、PNC分别对应于无人车的驱动、感知、规划控制模块,不一样模块之间经过消息传递连接。
Driver与Perception模块运行在OS Process1,PNC运行在OS Process2 。
不一样模块均包含Cyber RT Task(用橙框标注),并建立了异步OS Thread(用蓝框标注)。
CPU结构:4物理核,UMA构架。
内存:16G。
在接下来的配置中,指望达成以下结果:
OS Process1与OS Prcess2分别各自占用一半CPU资源。
两个进程中的Cyber RT调度器分别配置CPU亲和性以及Kernel调度策略。
Cyber RT Task根据关联关系分别设置优先级及调度策略。
给出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。
咱们将前两个物理核分配给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调度配置:
相同链路Task尽可能绑定到相同Processor上,提升Cache locality 。
相同链路Task,子节点Task优先级高于父节点Task,好比感知模块中Recognition优先级要高于Segmentation。
处于同Processor上Task们,总处理时延最大值不能高于链路处理周期,保证传感器消息处理实时性。在本案例中,为了简洁性,暂不考虑该场景。
暂时不能进行绑定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}
原则上讲,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框架在用户空间对算法层异步任务OS Process、OS Thread、CyberRT Task的CPU计算资源的总体统一控制以及数据与协程任务驱动模型的操做流程。相关详细的示例配置以及实车的调度器配置,咱们均可以在apollo/cyber/conf目录下找到。须要进一步说明的是,Cyber RT对车载环境中的系统中断、 kwork的CPU计算资源控制也作了考虑,但这部分须要Root权限,被放到了咱们定制的Base OS中,故而没有在当前文章中作出介绍。