APP下载

Nucleus PLUS SMP的任务管理机制研究与测试

2018-09-07,,,

单片机与嵌入式系统应用 2018年9期
关键词:亲和性任务调度测试用例

,,,

(许继电气股份有限公司,许昌 461000)

引 言

随着电力系统继电保护产品的集成度不断增加和产品性能的要求持续提高,多核处理器技术的应用应运而生。要想有效发挥多核处理器的性能,操作系统是关键,因而操作系统对多核处理器的支持也成为业界的研究热点[1]。只有充分了解操作系统在多核模式下的任务调度机制和管理策略,在此基础上结合应用需求对任务进行合理分配,才能达到兼顾性能和效率的目的。

本公司的电力系统保护控制产品基于美国ATI公司的Nucleus PLUS操作系统进行开发,出于兼容性和继承性的需要,在进行多核处理器开发时选用支持对称多核处理器的操作系统Nucleus PLUS SMP。单核版本和SMP版本最大的区别是任务管理,为了充分发挥多核处理器性能,本文基于SMP架构处理器双核ARM Cortex-A9 MPCore,研究分析了Nucleus PLUS SMP的任务管理机制,建立了测试环境,并提出了一套测试用例,实现了对多核操作系统任务调度的测试研究。

1 Nucleus PLUS SMP任务管理机制研究

任务是相对独立的可执行单元和基本调度单元。每个任务都有独立的堆栈空间和任务控制块(TCB)。TCB描述了任务的状态、调度信息和控制信息。Nucleus任务优先级的范围为0~255(0代表最高优先级)。Nucleus任务调度策略为高优先级优先调度和时间片轮转[2]调度结合使用。将任务按优先级分组,组间采用高优先权优先调度算法,而组内优先级相同的任务则按时间片轮转法调度。

为支持在SMP处理器上运行,Nucleus PLUS SMP任务管理模块在就绪任务的CPU归属方面,支持软亲和性、硬亲和性和调度域划分[3],就绪队列模型和调度策略等也随之改变。使用自旋锁机制来实现多核间的互斥同步,通过核间中断(IPI)来实现核间通信。

1.1 软亲和性(soft-affinity)

软亲和性即根据调度历史来影响任务再次调度时的目标CPU,其目的是提高CPU Cache命中率,提高运行效率。任务上次运行所在的core记为prev_core,任务重新调度时的软亲和性包括两种情况:①多个CPU空闲,prev_core为其中之一;②多个CPU上运行着优先级相同的最低优先级任务,prev_core为其中之一。这两种情况下,任务被再次调度到prev_core上。软亲和性策略中任务和prev_core的亲和性较弱,让位于高优先权调度策略。例如:任务A的prev_core为core0,高优先级任务A被重新调度时,如果core0上运行中优先级的任务B,core1上运行低优先级任务C,任务A则被调度在低优先级任务C所在的core1上。

1.2 硬亲和性(hard-affinity)

硬亲和性限制任务只能在一组CPU上运行。硬亲和性用于:①对于性能要求较高的任务,提高其Cache命中率;②任务使用了只对某些CPU可见的外设。

1.3 调度域(sched-domain)

Nucleus PLUS SMP的调度域分为两种:SMP调度域和BCD调度域。一个CPU只能属于一个调度域,且BCD调度域不能包含启动CPU,每个任务也只能隶属于一个调度域。

系统启动后,只有一个SMP调度域(系统调度域),它包含所有CPU。用户可通过NU_BCD_Multicore_Create系统函数在某些CPU上创建BCD调度域,此操作会将这些CPU从SMP调度域中清除。通过NU_BCD_Task_Add函数为BCD域分配任务(记为BCD tasks),当某个任务属于某个BCD调度域后,调度程序只在该BCD域上运行该任务,即使该BCD有CPU空闲,SMP调度程序仍不会将其用于其他任务。这一点与hard-affinity有所不同,对于硬亲和性绑定的CPU,当其空闲或者优先级比其绑定任务更高的其他任务就绪时,该CPU仍参与SMP调度。对于硬亲和性绑定的任务,其隶属的调度域为其绑定的CPU所在的调度域。

以8核SMP处理器架构为例,假如:①在CPU2、CPU3、CPU4上创建一个BCD调度域(记为BCD1);②在CPU5、CPU6上创建另一个BCD域(记为BCD2);③创建任务T1~T8,其中T1和T2分配给BCD1, T3和T4分配给BCD2,T5和T8硬亲和性绑定在CPU7上。

调度域划分和任务隶属情况如图1所示。

图1 调度域划分和任务隶属情况

1.4 就绪队列模型

就绪队列模型用于解决SMP系统中任务排队时CPU归属问题。一般有两种队列模型:全局队列模型和局部队列模型。对于全局队列模型,所有CPU共享一个就绪队列,优点是自然实现了负载均衡,缺点是互斥访问全局队列带来的性能损耗以及Cache命中率低。对于局部队列模型,每个CPU分配一个就绪队列,优点是充分利用CPU上的Cache热度,缺点是负载均衡性差[4]。Nucleus SMP综合使用了这两种队列模型,其就绪队列模型设计如下:

① 为每个调度域设置一个全局就绪队列(记为GRQ),SMP或BCD调度域中的所有任务共享该GRQ。

② 为每个CPU设置了一个局部/私有就绪队列(记为LRQ),hard-affinity任务在其绑定的CPU的LRQ中排队。

对于每个就绪队列,Nucleus SMP按优先级将其划分成256个子队列(实现为双向链表),并利用“任务控制块指针”(TC_TCB*)数组来管理子队列的头指针。

对于第1.3节中所举例子,假如T1~T8均为就绪状态且优先级均为5,则就绪队列状态如图2所示。注意:T5和T8为hard-affinity任务,它们的调度域虽为SMP调度域,但在其绑定的CPU7的LRQ中排队。

图2 就绪队列状态

1.5 任务管理相关数据结构及调度策略

1.5.1 任务管理相关的数据结构

(1)任务控制块(TC_TCB)

为支持affinity和sched-domain,Nucleus SMP在TC_TCB中主要增加表1所列的数据成员。

表1 任务控制块中任务调度有关的属性

(2)CPU调度上下文(TC_CPU_CB)

每个CPU均具有一个独立的上下文,该结构主要属性如表2所列。

表2 TC_CPU_CB属性

(3) “调度域”(TC_SCHED_DOMAIN)

每个调度域均定义了该类型的实例,如表3所列。

表3 调度域定义的数据类型

(4) “就绪队列”(TC_RQ)

每个CPU的LRQ和每个调度域的GRQ均采用的数据结构如表4所列。

表4 就绪队列的数据结构

(5)TCD_Sched_Change_CPUS

要在哪些CPU上进行任务调度,在进行任务调度前需设置此变量。

1.5.2 调度策略

下面介绍各种任务调度时机及每种情况下的任务调度策略。

(1)阻塞态变为就绪态

在创建新任务、任务阻塞等待的系统资源可用等情况下发生。

当任务从阻塞态变为就绪态时,将该任务插入其对应的就绪队列。如果该任务的优先级大于就绪队列的tc_high_ready_task_priority,则根据任务所在调度域的tc_low_sched_task_priority、tc_low_sched_task_cpus、软硬亲和性,设置TCD_Sched_Change_CPUS。然后调用TCCT_Control_To_System函数触发任务调度。在此策略中,高优先级任务抢占其调度域中最低优先级任务,减少了全局任务切换次数[5]。

(2)运行态变为就绪态

在更高优先级任务就绪、任务主动出让CPU和时间片用完等情况下发生。

将该任务插入其就绪队列。TCD_Sched_Change_CPUS设置为任务当前运行的CPU,然后调用TCCT_Control_To_System函数触发任务调度。

(3)运行态变为阻塞态

在请求的系统资源不可用、进入睡眠等情况下发生。

将TCD_Sched_Change_CPUS设置为任务当前运行的CPU,调用TCCT_Control_To_System函数触发任务调度。

上述3种任务调度发生情况均调用了TCCT_Control_To_System,其处理流程如图3所示。

图3 TCCT_Control_To_System处理流程

从中看出,当要发生任务调度的CPU不是当前CPU时,会向目标CPU发送IPI。目标CPU接收到IPI后,在IPI处理程序(ICC_Handle_IPI)中保存当前运行任务上下文,并调用TCCT_Schedule进行任务切换。

TCCT_Schedule函数处理流程如图4所示。

1.6 多核下任务的互斥与同步

图4 TCCT_Schedule处理流程

Nucleus PLUS SMP提供自旋锁机制来实现任务/中断间的互斥与同步。自旋锁是防止多处理器并发的一种锁机制[6],它有两种状态:“加锁”状态和“解锁”状态。任务或中断处理程序请求自旋锁时,如果该锁为“解锁”状态(该锁可用),则尝试将该自旋锁置为“加锁”状态;若加锁成功,代码继续进入临界区;如果该锁为“加锁”状态(该锁不可用),则进入忙等。“加锁”动作是一次“read-modify-write”操作,这个操作必须是原子的,这样才能保证即使多个任务在给定时间自旋,也只有一个线程能获取该锁。这就引入了一个新的问题:多核架构下,如何保证“read-modify-write”操作的原子性? 对于单核架构,简单的关中断即可实现原子操作。对于多核架构,由于多核上任务真正并行执行,用关中断实现原子操作失效。本文使用ARM Cortex-A9处理器,其在内存访问上增加了独占监测(Exclusive monitors)机制,并增加了LDREX和STREX指令。基于该处理器的自旋锁通过这两条指令实现了“加锁”的原子操作。

2 Nucleus PLUS SMP任务调度测试

2.1 测试环境搭建

测试环境是由PC机、BDI3000、目标系统组成。在PC机上,使用Sourcery Code Bench集成开发环境来编辑、编译测试程序。在目标开发板Zynq-7000[7](双核ARM Cortex-A9 MPCore)上运行测试程序。

测试环境搭建如图5所示。

图5 测试环境搭建

通过两种手段查看测试结果:

① 测试程序从目标系统的串口输出某些运行节点下任务、信号量等内核对象的状态,将其发送至PC机。

② Nuclues Trace作为Nuclues Kernel的嵌入式代码模块,跟踪Kernel运行期间的数据,通过JTAG、仿真器将其发送给PC机。PC端使用可视化分析界面查看跟踪这些数据。图6为任务时序分析图。

图6 任务时序分析图

2.2 测试用例设计

任务管理测试分为下面几类:任务状态机测试、调度算法测试、负载均衡测试、软亲和性测试、BCD调度域测试、硬亲和性测试、核间通信测试。

2.2.1 任务状态机测试

(1)就绪态转运行态/运行态转就绪态

测试用例1:优先级位于Top-N(对于双核,N为2)的任务A就绪后运行。

测试用例2:TA主动出让CPU(NU_Relinquish),就绪队列中下一个同优先级任务运行。

测试用例3:TA时间片用完,就绪队列中下一个同优先级任务运行。

(2)运行态转阻塞态

测试用例1:因请求系统资源而阻塞。

测试用例2:调用NU_Sleep,进入睡眠。

测试用例3:调用NU_Suspend_Task,无条件阻塞。

(3)阻塞态转就绪态

测试用例1:所请求信号量资源可用。

测试用例2:睡眠时间到。

测试用例3:调用NU_Resume_Task,唤醒无条件阻塞任务。

2.2.2 调度算法测试

测试用例1:高优先级抢占原则。两个核上分别运行中等优先级和低优先级任务。高优先级任务就绪后,应抢占低优先级任务。

测试用例2:同优先级时间片轮转。创建4个相同优先级的SMP任务,它们应轮流被调度。

2.2.3 负载均衡测试

对于N核SMP系统,Nucleus SMP 将就绪队列中优先级最高的前N个任务调度到N个可用核上。Nucleus SMP每个调度域内共用一个就绪队列,实现了负载均衡。负载均衡避免了核的忙闲不均,提高了系统吞吐量。

测试用例1:SMP调度域内负载均衡测试。

① 创建SMP任务TA、 TB 和TC。优先级关系:TA>TB>TC。预期优先级最高的TA和TB任务分别调度到2个核上运行。

② TA或TB运行完毕或阻塞后,预期TC被调度到空闲核上运行。

测试用例2:BCD调度域内负载均衡测试。

用例与上面类似,区别为任务是BCD任务。

2.2.4 软亲和性测试

在下面情况下,TA应调度到core-prev上:

① TA被重新调度时,当前空闲的核包括core-prev。

② 多个相同优先级的任务运行在N个核上,其中包括TA的core-prev,更高优先级的TA被重新调度运行。

2.2.5 BCD调度域测试

Nucleus SMP允许某些CPU作为BCD,并为之分配任务。

测试用例1:任务只运行在其指定的BCD域上,即使其他调度域的CPU空闲。

测试用例2:即使BCD域的某个CPU空闲,调度程序仍不会将其用于非本调度域中的其他任务。

2.2.6 硬亲和性测试

测试用例1:任务只能运行在其硬亲和性绑定的CPU上。

测试用例2:对于被硬亲和性绑定的CPU,当其空闲时,仍可参与其所在调度域内其他任务的调度。

测试用例3:对于被硬亲和性绑定的CPU,当其上运行的硬亲和性任务的优先级小于调度域某个就绪任务的优先级时,硬亲和性任务被抢占。

2.2.7 核间通信测试

测试用例1:阻塞不同核上的任务。

① TA绑定在CPU0上;TB绑定在CPU1上。

② TA调用NU_Suspend_Task阻塞TB,预期TA被阻塞。

测试用例2:唤醒不同核上的任务。

① TA绑定在CPU0上;TB绑定在CPU1上。

② TA调用NU_Retrieve_Events获取事件1,阻塞;TB调用NU_Set_Events,设置事件1。预期TA被唤醒。

测试用例3:任务核间迁移。

① 创建硬亲和性绑定在CPU1上的任务TB,TB在CPU1上运行。

② 创建SMP任务TA,TA优先级大于TB,TA在CPU0上运行。

③ 在CPU1上创建BCD,并将TA指定给BCD。预期结果为TA迁徙到CPU1,抢占TB运行。

2.2.8 任务同步/互斥测试

测试用例1:任务与任务之间使用自旋锁进行同步/互斥。

① 创建自旋锁。

② TA调用NU_Spinlock_Obtain请求自旋锁,预期TA请求自旋锁成功。

③ TB调用NU_Spinlock_Obtain请求自旋锁,预期TB进入“忙等”。

④ TA调用NU_Spinlock_Release释放自旋锁,预期TB请求自旋锁成功。

测试用例2:任务与中断之间使用自旋锁进行同步/互斥。测试步骤同上。

测试用例3:中断与中断之间使用自旋锁进行同步/互斥。测试步骤同上。

结 语

浮明军、姬希娜(高级工程师),王振(工程师),许英豪(助理工程师):主要研究方向为智能变电站控制保护嵌入式软件平台的研发测试。

猜你喜欢

亲和性任务调度测试用例
部分蔷薇与现代月季杂交亲和性研究
基于SmartUnit的安全通信系统单元测试用例自动生成
基于改进NSGA-Ⅱ算法的协同制造任务调度研究
荔枝高接品种的选择
基于时间负载均衡蚁群算法的云任务调度优化
基于混合遗传算法的回归测试用例集最小化研究
4个苹果观赏品系开花、授粉习性及花粉管萌发的荧光显微观察
不结球白菜与西洋菜远缘杂交亲和性研究
云计算环境中任务调度策略
云计算中基于进化算法的任务调度策略