ARMv8-A编程指导之多核处理器(1)

        ARMv8-A架构提供了支持包含多个处理器的级别的系统。一个ARM多核处理器如Cortex-A57MPCore和Cortex-A53MPCore可以包含一个到四个core。使用Cortex-A57和Cortex-A53处理器通常都是以这种方式实现。一个多核处理器可能包含有独立执行指令的能力的多个core,这被认为单个unit或cluster。当不使用节省功耗时,ARM多核技术使能一个cluster中的四个core都关闭,比如当设备负载较轻时或在standby模式时。当要求高性能时,每个处理器用来满足要求,但仍共享工作负载来保持功耗尽可能少。

        多处理器可以被定义用来包含多个core的单个设备中同时运行二个或多个指令。现在广泛应用于通用应用处理器和嵌入式系统中。

        多核系统的整个功耗可以明显低于单处理器系统。多核可能使执行完成更快,因此系统的一些core可能在更长的周期内完全下电。相反,多核系统可能运行比单核系统运行更低的频率来完成相同的吞吐量。更低功耗处理器或更低的供给电压会导致更低的功耗和减少能量的使用。大多数系统不允许核的频率单独在修改。但是,每个核可以有动态的时钟门控,用于功耗的节省。

        多核也让系统配置有更多选择。比如,你可能使用多个独立的核,一个用于处理硬实时要求,其他用于要求高性能的应用。这可以被合并到一个多核系统中。

        多核设备也更可能比单核设备反应快。当中断被分发到多个核时,多个核可以响应这个中断,每个核上服务的中断更少。多核也使后台进程能够同时与重要但不相关的前台进程同时执行。

1 多处理器系统

        我们可以将系统分为:

  1. 包含单核的单处理器;
  2. 多核处理器,如Cortex-A53,有能力单独执行指令的多核,可以被视为单个unit或cluster,系统设计者或操作系统可以将来自应用层的资源进行抽象;
  3. 多cluster,每个cluster包含多个corel。

        本文中描述的多处理器系统遵循此定义。其它的操作系统中可能有不同的含义。

1.1 决定代码执行在哪个核上

        一些软件操作依赖于代码运行的core。比如,全局初始化通常由执行在单个core的代码发起,然后在所有core上进行本地的初始化。

        多核亲和寄存器MPIDR_EL1使能软件决定软件运行在哪个core上,无论是在一个cluster还是有多个cluster的系统,它决定哪个core以及哪个cluster上执行。

        在一些处理器配置的U位指示它是否是单核或多core的cluster。亲和域给出了本core与其它core相关的层次描述。通常,affinity0为cluster中在core ID, affinity1为cluster ID。

NOTE: 运行在EL1的软件可以运行在hypervisor管理的虚拟机中。为了配置虚拟机,EL2和EL3可以在runtime时设置MPIDR_EL1为不同值。因此一个特定的虚拟机可以看到一个连续的,每个虚拟core有唯一值。虚拟core和物理core在关系由hypervisor控制,随着时间也可能改变。

        MIPDR_EL3包含每个物理core的不修改值ID。两个core不能共享相同的MPIDR_EL3的值。

1.2 对称多处理器

        SMP是动态决定单个core的角色的软件架构。cluster中的每个core对内存和共享的硬件有相同视角。任何应用,进程,或任务可以运行在任何core上,OS调度器可以动态的将任务在core之间进行迁移来完成优化系统负载。多线程的应用可以一次运行在多个core上。OS可以隐藏应用的复杂性。

        在本指导中,在操作系统下的应用的每个运行实例称为process。应用可以通过调用到系统库来发出很多操作,这些系统库提供库代码中的某些函数,同时也作为内核操作的系统调用的封装。单个process有相关的资源,包括栈,堆和常量数据区,以及属性如调度优先级设置。进程的内核视图成为task。进程是task的集合,它们共享某些公共的资源。其他操作系统可能有不同的定义。

        当描述SMP操作时,我们使用术语kernel来表示操作系统的一部分,它包含异常处理,设备驱动,以及其他资源和进程管理代码。我们也假定任务调度器的存在,任务调度器通常称为使用定时器中断。调度器负责在核上多个任务之间的时间片,动态决定单个任务的优先级,决定下一步运行哪个任务。

        线程为执行在相同进程空间的单独任务,该地址空间使应用的多个分开部分可以并行在不同核上执行。他们也允许应用的一部分在执行,而另一部分正在等待资源。

        通常,进程中所有的线程共享多个全局资源(包括相同的内存映射,可以访问任何打开的文件和资源处理)。线程也有它们自己的本地资源,包括它们自己的栈和寄存器,它们用于内核的上下文的保存和恢复。但是,这些资源是本地的,并不意味着任何线程的本地资源可以保证不被其他线程的不正确访问。线程单独调度,即使在单个进程中,他们也可能有不同的优先级。

        具有SMP能力的OS提供了有效的核资源抽象给应用。多个应用啊可以同时执行在SMP系统中,而不需要重新编写或修改代码。一个传统的多任务OS使系统可以在同一时间运行多个任务和活动,在单个core或多个core上。在多核系统中,我们可以真正并发,多个任务通常同时执行,并发在多个核上。这些跨core分发和管理的角色由OS执行。

        通常,OS任务调度器可以在系统中跨core分发任务。这个特征成为负载均衡,目的是为了获取更好的性能,或节省功耗。比如,在某种负载下,如果实现该负载的任务仅调度在几个core上,可以完成节省功耗。这将允许多个资源在长时间内空闲,因此节省了功耗。

        在其他的场景,如果任务扩展更多的core,负载的性能会增加。这些任务将执行更快,而不需要被其他任务打扰。

        另外其他的场景,可能将任务执行在低的频率的多核上比执行在更高的频率上的更少的核上更合适。这些操作是在节省功耗和性能之间得到平衡。

        SMP系统的调度器可以动态的为任务提供优先级。动态的任务优先级可以在当前任务睡眠时使其他任务可以执行。在LINUX,比如,性能受处理器活动限制的任务可以降低其优先级,以支持性能受IO活动限制的任务。IO限制的任务会中断计算限制的进程,因此它会发出IO操作然后重新休眠,处理器在IO完成后执行计算限制的代码。

        中端处理可以跨核进行负载均衡。这可以帮助改善性能或节省功耗。在core间均衡负载或保留core给某些特定的中断,可以减少中断时延。这也会导致在不使用cache的场景优化性能。

        使用更少的core来处理中断可以导致在长时间内更多资源空闲,导致以减少性能为代价节省功耗。Linux内核不支持自动中断负载均衡。但是,内核提供了机制来改变对某些core的中断绑定。也有一些开源项目如irqbalance,可以使用这些机制来将中断重新安排到这些core上。irqbalance能够意识到系统的属性如共享cache层次(哪些核有共同的cache)和电源域的布局(那些core可以单独下电)。它可以决定最好的中断与core的绑定。

        SMP系统会在cluster中的core中共享内存。为维护应用软件的要求的抽象级别,硬件必须提供持续和一致的内存视角。

        内存的共享区域的修改必须对所有的core可见而不需要任何显式的软件一致性管理,虽然同步指令比如barrier被要求保证更新以正确的顺序看到。类似的,内存映射的任何更新,比如因为页请求,新内存的分配,映射一个设备到当前虚拟地址空间,必须一致的呈现给所有core。

你可能感兴趣的:(ARMv8-A编程指导手册,SMP)