1. 多核SMP架构与VxWorks演进
1.1 从单核到多核:调度问题的本质变化
在单核VxWorks系统中,调度器的核心任务非常清晰:在任意时刻,CPU上只能运行一个任务,调度算法只需在就绪队列中选出优先级最高的任务并切换上下文。Wind内核采用基于优先级的抢占式调度,256个优先级(0最高,255最低),同优先级任务可选时间片轮转。此时“并发”只是宏观上的假象,微观上任务严格串行执行,共享数据的竞争仅发生在任务与中断之间。
进入多核时代后,情况发生了根本性变化。假设一个四核处理器上同时有4个高优先级任务就绪,它们可以真正并行运行。这带来三个新的调度挑战:
- 任务放置问题:新创建或唤醒的任务应该放到哪个CPU的就绪队列?是固定绑定还是动态迁移?
- 负载均衡问题:当某个CPU空闲而另一个CPU积压多个就绪任务时,如何把任务“搬”过去?搬运的时机和频率如何控制?
- 数据一致性成本:多核并行访问共享数据结构(如就绪队列、调度器锁)时,必须用自旋锁或原子操作保护,这些同步开销会随核数增加而放大。
因此,多核调度不是单核调度的简单复制,而是要在“并行收益”与“同步开销”之间做权衡。
1.2 SMP对称多处理基本模型
SMP(Symmetric Multiprocessing,对称多处理)的核心特征是:所有CPU核在硬件上对等,共享同一物理内存空间和同一份操作系统映像,每个核都能访问全部外设和中断控制器。与之相对的是AMP(非对称多处理),每个核运行独立的OS实例,核间通过共享内存或消息通信。
在SMP模型中,VxWorks内核维护一个全局就绪队列集合,每个CPU有各自的本地就绪队列,同时存在一个全局调度器锁来保护关键区。任务可以在任意CPU上运行,也可以被迁移。中断可以被路由到指定CPU,但同一中断源通常只由一个CPU处理,以避免中断嵌套的复杂性。
需要特别注意的是,SMP下“优先级”的含义没有改变,但“最高优先级任务”可能同时有多个实例在不同核上运行。因此,调度器必须保证:任何时刻,每个CPU上运行的任务优先级都不低于该CPU就绪队列中的其他任务;同时,全局最高优先级任务必须至少在一个CPU上运行。
1.3 VxWorks 7 SMP关键特性与硬件抽象层要求
VxWorks 7对SMP的支持不是简单打补丁,而是从内核到BSP的体系化重构。其关键特性包括:
- 统一内核映像:所有CPU核运行同一份VxWorks内核,通过CPU索引(cpuIndex)区分当前核,避免AMP下多份映像的维护负担。
- 细粒度锁与无锁数据结构:内核对象(任务、信号量、消息队列)的锁粒度被细化,部分只读路径采用RCU或原子操作,减少核间争用。
- CPU亲和性(Affinity):任务可绑定到指定CPU集合,适合缓存局部性敏感或需要隔离关键任务的场景。默认不绑定,允许迁移。
- 中断亲和性:外部中断可路由到指定CPU,避免所有中断集中在一个核上形成瓶颈。
- 核间中断(IPI):用于触发远程CPU的调度、TLB刷新、缓存一致性维护等操作。
硬件抽象层(HAL)必须满足以下要求才能支撑SMP:
- 提供原子指令(如LDREX/STREX、CAS)用于实现自旋锁和引用计数。
- 提供内存屏障指令(DMB/DSB/ISB),保证多核间的内存访问顺序。
- 提供每核私有存储(如TPIDRPRW寄存器)用于存放cpuIndex和当前任务指针。
- 中断控制器支持IPI分发和中断亲和性配置(如GIC-400的SPI/PPI路由)。
- 启动时完成从核(secondary core)的唤醒与初始化,主核负责引导并释放从核进入调度循环。
1.4 一个可观察的调度场景
假设四核VxWorks 7系统上运行以下任务(优先级数值越小越高):
| 任务 | 优先级 | CPU亲和性 | 状态 |
|---|---|---|---|
| T_high_A | 5 | CPU0 | 就绪 |
| T_high_B | 5 | CPU1 | 就绪 |
| T_mid | 12 | 无绑定 | 就绪 |
| T_low | 20 | 无绑定 | 就绪 |
初始时,CPU0运行T_high_A,CPU1运行T_high_B,CPU2和CPU3空闲。负载均衡器发现CPU2/3空闲,而T_mid和T_low在全局就绪队列中等待,于是将T_mid迁移到CPU2,T_low迁移到CPU3。此时四个核都在运行任务,系统吞吐量提升。若T_high_A阻塞(如等待信号量),CPU0会立即从本地或全局队列选取下一个最高优先级任务,可能是T_mid(如果它未被绑定且仍在CPU0队列中)。
这个场景说明:SMP调度的核心不是“让每个核都忙”,而是“让最高优先级任务尽快获得CPU,同时控制迁移和锁的开销”。实际工程中,可以通过VxWorks的taskCpuAffinitySet()设置亲和性,通过spawn或taskSpawn的选项控制任务初始CPU,并通过kernelTimeSlice调整同优先级轮转时间片。
ti(task info)查看各任务当前所在CPU和状态,使用spy或windView观察任务迁移和核间负载分布。若发现某个核长期空闲而其他核积压,应检查任务亲和性是否过度绑定,以及全局调度器锁的争用计数是否异常升高。
1.5 本章小结
从单核到多核,VxWorks的调度挑战从“选哪个任务”扩展为“选哪个任务、放哪个核、何时迁移、如何同步”。SMP对称多处理模型通过共享内存和统一内核映像获得并行能力,但代价是锁竞争和缓存一致性开销。VxWorks 7通过细粒度锁、CPU亲和性、IPI和HAL原子指令支持,使SMP调度在实时性和吞吐量之间取得平衡。理解这些基础,是后续分析多核调度延迟、优先级反转和性能瓶颈的前提。