《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 设计应用 > 多核系统中提升启动速度之策略
多核系统中提升启动速度之策略
来源:电子技术应用2014年第3期
王 江
(上海贝尔股份有限公司N&P,上海201206)
摘要: 快速启动能力是衡量产品性能的一个重要指标。针对应用越来越广泛的多内核处理器,从优化启动流程、改进模块的加载和初始化、设计内核间通信机制等方面,介绍了缩短启动时间的一些经验,特别是启动任务的分配、串行执行到并行执行的转变、内存的分阶段初始化、PCIe总线的快速初始化等技巧。实际测试表明,新策略不仅有效地缩短了启动时间,而且具有易移植、可扩展等优点。
中图分类号: TP338.2
文献标识码: A
文章编号: 0258-7998(2014)03-0025-04
Strategy of accelerating booting process in multi-core systems
Wang Jiang
Alcatel-Lucent Shanghai Bell Co.,Ltd.N&P,Shanghai 201206,China
Abstract: The ability of fast boot is one of the key metrics of product performance. As multi-core microprocessors are being employed widely in more and more applications, the paper introduces some experiences to shorten the boot time, including optimizing boot process, improving the loading and initialization method of modules, designing communicating mechanism between cores, etc. It also elaborates some techniques, such as boot tasks assignment and parallelization, memory division and initialization, fast-initialization of PCIe bus. Experiments verify that the new strategy can not only shorten the boot time, but also be transplantable and scalable.
Key words : boot;PCIe;multi-core microprocessor

    快速启动能力是衡量产品性能的一个重要指标。无论是消费类电子产品(例如手机、电脑、电视机),还是专业的通信电子设备(例如示波器、网关、服务器),启动速度快无疑能给用户留下美好的第一印象。虽然电子设备的“心脏”越来越多地选用了多核处理器,但是目前大部分启动代码还停留在单内核处理器的思维框架中,没有能够充分利用多内核处理器的长处,而越来越多的外部器件却在另一方面悄悄地延长了启动时间。
    为了弥补这一不足,突破传统单核启动的思维框架,本文以一个典型的嵌入式系统为例,对加快系统启动速度进行了研究。
1 典型的系统架构和启动过程
1.1 系统架构

    智能通信电子产品的典型架构是以CPU(中央处理器)为核心,根据产品需求辅以内存、硬盘、网卡、USB、串口等各种外设,如图1所示。

    系统的核心是飞思卡尔(FreeScale)公司开发的32位PowerPC架构处理器MPC8572E[1],主频最高可达1.333 GHz。芯片集成了2个完全相同的高性能e500内核,每个内核各包含32 KB一级指令缓存和32 KB一级数据缓存。芯片还集成了丰多彩富的内部功能模块和外设接口,包括:2个内核共享的1 MB容量的二级缓存、2个64位DDR2/DDR3内存控制器、1个可编程的中断控制器、1个安全引擎、2个I2C总线控制器、2个异步串口控制器、1个增强型本地总线控制器、4个支持10/100/1 000 MB/s的以太网接口、3个符合PCIe 1.0a标准的PCIe接口等。
    CPU、内存、闪存、串口和网口组成了一个常见的最小系统,其他模块则是锦上添花。处理器通过PCIe接口连接SATA/SAS控制器(例如LSI公司的SAS2008芯片),再外接SATA/SAS硬盘。实时时钟芯片(RTC)和温度感应器通过I2C总线与处理器相连。FPGA用于辅助CPU工作。这个系统具有强大的处理能力和灵活的可扩展性,适合于路由器、网关等多种应用场合。其他智能电子设备的控制系统的架构也大致如此,只是CPU可能替换成ARM、MIPS或x86等体现结构的处理器,外围器件有所增减,但是总体框架和启动过程大同小异。
1.2 启动过程
    该系统由业界常用的U-BOOT[2]引导启动。图2显示了多内核处理器系统中启动代码的工作流程。上电或重启后,内核0根据配置引脚的设定,选择从闪存中读取启动代码。其他内核保持Reset状态。内核0依次初始化了e500内核、第一个串口、一级数据缓存和指令缓存、二级缓存、I2C总线设备、内存。因为初始化内存时CPU需要访问内存条上的SPD(SPD是存储内存条规格参数的EEPROM芯片),所以I2C总线的初始化必须在内存初始化之前完成。之所以较早地初始化串口,是为了尽早建立人机交互的环境,以方便用户判断系统启动到各个阶段的状态。然后,内核从闪存中读取FPGA配置文件并且下载到FPGA芯片中,再初始化PCIe设备、网口、SAS/SATA控制器、硬盘和文件系统。接着,内核0释放其他内核的Reset信号。

    其他内核也从闪存中读取启动代码,依次初始化e500内核、一级数据缓存和指令缓存,然后通过共享内存的方式(也可以通过内部寄存器或者内核间中断等方式)通知内核0“我准备就绪了。”一旦内核0发现其他内核准备就绪后,就从硬盘中读取操作系统的镜像文件,校验正确后加载执行。如果内核0发现其他内核启动失败,则重新发出Reset信号,要求其他内核重复初始化的过程。
    经过测试,整个系统的启动时间约9 s。表1列举了耗时超过0.1 s的模块,其他模块的耗时微乎其微,可以忽略不计。从启动过程可以看出,所有的初始化任务基本上都由内核0承担,总的启动时间是各模块初始化时间的总和。显然,这种传统的多核启动方式没有利用多内核的优势,还停留在单核启动的框架中。
2 启动过程的改进
    在多核系统中,为了高效地利用多个核的并行工作,启动代码的设计需要从传统意义上的任务串行机制转换到任务并行机制,并且要注重多内核间的协作。改进后的启动方案不仅充分利用了多内核的优势,将一些模块的初始化任务分配给了其他内核,而且优化了一些模块的初始化方法,建立了内核间有效的通信机制。
    如何将模块分配给其他内核初始化,分配原则之一是独立性。如果该模块和其他模块没有相互依赖关系,则可以将该模块分配给其他内核加载。原则之二是耗时的模块尽量分配给不同的内核加载,即每个核承担模块的总耗时尽量平均,尽可能减少等待时间。据此优化为图3所示的启动流程。

    启动过程中,内核0仍然扮演主力队员的角色,首先初始化e500、串口、一级缓存和二级缓存,然后只初始化一部分内存,而不是全部内存。这一部分内存姑且称为基本内存,即启动代码所要用到的内存,本系统中是32 MB。因为内存的初始化比较费时,主要时耗不在内存控制器的初始化上,而在于将所有的4 GB内存清零,所以把内存划分为一大一小两部分初始化,将容量大的那部分内存分配给其他内核初始化,有利于提升整体的启动速度。
    完成内核、串口1和基本内存的初始化之后,内核0先把启动代码从闪存复制到内存中,再释放其他内核的Reset信号。其他内核立刻初始化e500内核和内嵌的一级缓存,然后通知内核0“我已经准备好了。”内核0得知其他内核准备就绪了,就开始分配其余的初始化任务。其他内核依次初始化剩余的大部分内存,下载FPGA的配置文件,初始化网口,最后等待操作系统。与此同时,内核0初始化PCIe设备、SAS/SATA控制器及磁盘,加载文件系统,最后从磁盘中读入操作系统文件,计算校验和,引导操作系统的启动。
    除了改进启动流程之外,充分利用硬件特性,优化一些模块的初始化方法和工作机制,设计高效的内核间通信机制,也可以提升启动速度。
    (1)内存初始化。内存初始化的主要耗时动作是清零。目前主流的处理器都集成了DMA(直接存储器访问)引擎,DMA引擎就是为了降低CPU负载而设计的。测试发现,与处理器直接清零内存操作比较,采用DMA方式,速度可以提升一倍。并且,在DMA引擎清零的同时,CPU还可以承担其他工作,例如下载FPGA配置文件。此外,如果内存设置为交织模式,其吞吐量可以翻番,从而减少耗时,进一步提升启动速度。
    (2)PCIe初始化。PCIe[3]总线在软件上兼容PCI、PCI-x总线,PCI或者PCI-x器件可以通过PCIe桥设备连接到PCIe的总线拓扑中。PCIe总线的拓扑结构像一颗树,最多允许拥有256条总线,每条总线上最多允许32个设备,每个设备上最多可集成8个功能模块。一般采用深度递归算法,从根节点出发,遍历整棵树,找到存在的有效设备并初始化。初始化的操作就是分配总线号、设备号、中断号和地址空间等。其中,PCIe拓扑结构的遍历过程是比较耗时的一个操作。
    实际上,对于电子产品而言,一旦电路板装配好了,除了PCIe插槽上的设备未定之外,其他PCIe设备都固定了,是已知数,所以对于已知设备可以省略扫描这个步骤。它的相关信息可以存储在闪存的指定区域,启动代码直接从这个区域读取。如果电路板上没有PCIe插槽,则整个PCIe拓扑结构的信息都可以保存在闪存中,彻底省略了遍历过程,耗时微乎其微。对于插槽上的未定设备,深度遍历的出发点可以从根节点出发改为从各个PCIe插槽出发,大幅缩小遍历范围,从而节省了大量时间。
    (3)简单高效的基于共享内存的内核间通信机制。内核之间为了紧密配合,相互间需要传递一些命令和数据,虽然有些处理器拥有特别的内核间的通信方式,例如博通公司XLR系统处理器的消息环机制[4](Message Ring),但是共享内存是一个比较通用的方法,不仅适合于内核之间,也适合于处理器之间以及处理器与外设之间的通信,可移植性较强。基于共享内存,设计一个简单高效的通信机制,有助于内核0与其他内核之间命令的上行下达。
    因为启动过程中内核0起主导作用,所以在内核0和其他每个内核之间都创建了一条通信通道,组成一个星形结构:内核0在中间,其他内核在四周,如图4所示。每条通道由收、发2个队列组成:内核0只能写发送队列,其他内核只能读发送队列;接收队列的操作相反,内核0只能读接收队列,其他内核只能写接收队列。
    读写队列的基本单位是数据块,即每次从队列中读取一个或多个数据块,或者往队列中写入一个或多个数据块。数据块由序列号、命令、数据长度、数据等域组成。发送队列数据块中的序列号是偶数,而接收队列数据块的序列号是奇数,每一个发送数据块都对应一个响应的接收数据块,它们的序列号相差1。发送队列数据块中的数据域是与命令相关的参数,接收队列数据块中的数据域是命令的执行结果。

 

 

    借助这个收发队列通信机制,内核0可以便捷地把初始化等任务分派给其他内核并得到反馈,有利于系统的可扩展性。例如系统中增加了一个新器件,内核0可以把新器件的初始化工作分配给一个比较空闲的内核,从而最大限度地减少对整个启动时间的影响。
    经过启动流程的改进、模块加载和初始化方式的优化、内核间高效通信机制的设计等工作,系统的启动时间大约缩短了50%,达到了比较满意的结果。目前多处理器的发展和应用如火如荼,希望本文所介绍的经验对各种体系结构的多内核处理器的启动代码设计都有所帮助。
参考文献
[1] FreeScale Semiconductor.MPC8572E PowerQUICC III  integrated processor hardware specifications,Rev.5[Z].2011.
[2] DENK W.The universal boot loader[EB/OL].[2013-07]. http://www.denx.de/wiki/DULG/WebHome.
[3] PCISIG.PCI Express base specification,revision 3.0[Z]. 2008.
[4] Broadcom Inc..XLR processor family data sheet,revision 2.00[Z].2008.

此内容为AET网站原创,未经授权禁止转载。