调度系统调度策略分为classic策略和choreography策略。
classic策略是一个较为通用的调度策略,如果对当前车上dag结构不清楚,建议用此策略。
choreography策略是基于对车上任务足够熟悉,根据任务的依赖执行关系、任务的执行时长、任务cpu消耗情况、消息频率等,对任务进行编排。
cyber/conf/example_classic_sched.conf:
scheduler_conf {
policy: "classic"
process_level_cpuset: "0-7,16-23"
threads: [
{
name: "async_log"
cpuset: "1"
policy: "SCHED_OTHER"
prio: 0
}, {
name: "shm"
cpuset: "2"
policy: "SCHED_FIFO"
prio: 10
}
]
classic_conf {
groups: [
{
name: "group1"
processor_num: 16
affinity: "range"
cpuset: "0-7,16-23"
processor_policy: "SCHED_OTHER"
processor_prio: 0
tasks: [
{
name: "E"
prio: 0
}
]
},{
name: "group2"
processor_num: 16
affinity: "1to1"
cpuset: "8-15,24-31"
processor_policy: "SCHED_OTHER"
processor_prio: 0
tasks: [
{
name: "A"
prio: 0
},{
name: "B"
prio: 1
},{
name: "C"
prio: 2
},{
name: "D"
prio: 3
}
]
}
]
}
}
每个配置属性的含义、影响:
-
groups:如2.1的配置示例,classic策略可以配置多个group,主要为了实现资源隔离、跨numa问题,比如一个进程产生的所有task在0-31号cpu上执行,内核的调度会将线程在0-31号cpu上切换,跨numa节点会给系统带来额外的开销,这里可以通过group将numa节点进行隔离,一个numa节点下的0-7,16-23号cpu划分到一个group中,另外一个numa节点下的8-15,24-31号cpu划分到另一个group,这样既保证了资源利用,也能避免跨numa节点带来的开销。
-
process_level_cpuset: 控制mainboard进程使用哪些cpu
-
affinity: 取值为range或者1to1,如第一个group,创建16个线程,在0-7,16-23号cpu上设置亲和性,每个线程都可以在0-7,16-23号核上执行。第二个group中,affinity为1to1,表示16个线程对应8-15,24-31号cpu,每个线程和一个cpu进行亲和性设置,能减少线程在cpu之间切换带来的开销,但是前提是开启的线程数和cpu数必须一致。
-
processor_policy和processor_prio: 这两个一般成对出现,processor_policy指设置线程的调度策略,取值为SCHED_FIFO(实时调度策略,先到先服务), SCHED_RR(实时调度策略,时间片轮转), SCHED_OTHER(分时调度策略,为默认策略),对于设置了SCHED_FIFO或者SCHED_RR的线程会更优先的得到cpu执行, 调度模型中设置processor_policy背景:为了保证主链路的任务或者其他一些实时task的优先执行。如果processor_policy设置为SCHED_FIFO/SCHED_RR,processor_prio取值为(1-99),值越大,表明优先级越高,抢到cpu概率越大。如果processor_policy设置为SCHED_OTHER,processor_prio取值为(-20-19,0为默认值),这里为nice值,nice值不影响分配到cpu的优先级,但是影响分到cpu时间片的大小,如果nice值越小,分到的时间片越多。
-
tasks:这里是对task任务进行配置,name表示task的名字,prio表示任务的优先级,为了提高性能,减小任务队列锁的粒度,调度模型中采用的是多优先级队列,也就是同一优先级的task在同一个队列里面,系统调度时会优先执行优先级高的任务。
例如拓扑结构为下图所示,对应2.1中的配置文件,那么A、B、C、D任务在第一个group中执行,E在第二个group中执行,对于没有出现在配置中的任务,比如F默认会放到第一个group中执行。 而且配置中我们对于任务进行了优先级设置,A、B、C、D优先级依次增大,正好对应下图的拓扑依赖关系,在链路中越靠后的任务优先级越高。这样设置的目的是解决任务优先级反转的问题。
cyber/conf/example_choreography_sched.conf:
scheduler_conf {
policy: "choreography"
process_level_cpuset: "0-7,16-23"
threads: [
{
name: "lidar"
cpuset: "1"
policy: "SCHED_RR"
prio: 10
}, {
name: "shm"
cpuset: "2"
policy: "SCHED_FIFO"
prio: 10
}
]
choreography_conf {
choreography_processor_num: 8
choreography_affinity: "range"
choreography_cpuset: "0-7"
choreography_processor_policy: "SCHED_FIFO"
choreography_processor_prio: 10
pool_processor_num: 8
pool_affinity: "range"
pool_cpuset: "16-23"
pool_processor_policy: "SCHED_OTHER"
pool_processor_prio: 0
tasks: [
{
name: "A"
processor: 0
prio: 1
},
{
name: "B"
processor: 0
prio: 2
},
{
name: "C"
processor: 1
prio: 1
},
{
name: "D"
processor: 1
prio: 2
},
{
name: "E"
}
]
}
}
choreography策略,主要是对主链路上的任务进行编排(choreography开头的配置),将非主链路的任务放到线程池中由classic策略(pool开头的配置)执行,choreography策略中classic线程池存在的意义:主链路的任务执行先后关系比较明确,但是存在一些其他链路的任务在不清楚前后拓扑关系的情况下,或者说未被编排的任务(包括Async创建的异步task),会被放到classic线程池中执行。
关于配置属性:
- affinity: 在2.2中进行了解释说明。
- choreography_processor_policy和choreography_processor_prio是设置编排线程的调度策略和优先级,这里设置SCHED_FIFO是为了保证主链路能够及时抢占cpu执行, pool_processor_policy和pool_processor_prio是设置classic线程的调度策略和优先级。
用2.3中的拓扑图来进行说明
A、B、C、D是主链路任务,都设置了processor属性,那么A、B在0号cpu上执行,C、D在1号cpu上执行。在同一个核上,A和B还设置了优先级,所以优先执行B,再执行A。
没有配置processor属性的任务E以及没有出现在task配置中的任务如F,则默认进入classic线程池中执行。
考虑到任务优先级、执行时长、频率与调度之间的关系,任务编排有如下几个依据:
- 同一个path的任务尽量编排在同一个processor,如果processor负载过高,将部分任务拆分到另外其他processor
- 同一个path上的任务从开始到结束,优先级逐级升高
- 不同path上的任务尽量不混排
- 高频&短耗时任务尽量排放同一processor
如果进程没有对应的调度配置文件,默认采用classic调度策略,开启调度任务线程数值为conf/cyber.pb.conf中default_proc_num设置的值
modules/dreamview/conf/hmi_modes/mkz_close_loop.pb.txt中,设置了两个process_group,分别为compute_sched/control_sched,也就是这两个进程启动时候,分别加载compute_sched.conf/control_sched.conf的调度配置文件。
另外要注意的是dreamview进程的process_group:dreamview_sched 是在modules/dreamview/backend/main.cc 中进行设置的,加载对应的调度配置文件dreamview_sched.conf。
默认调度策略采用classic策略,compute_sched.conf和control_sched.conf两个软链分别指向compute_sched_classic.conf和control_sched_classic.conf文件。可以通过将软链指向compute_sched_choreography.conf和control_sched_choreography.conf配置文件来切换到choreography策略。