说明:该系类文章更多的是从从哲学视角看 操作系统 这门学科。同时也是 操作系统的学习笔记总结。因为博主 这些年主要是以研究安卓系统和 嵌入式Linux为主,因此这个系类文章也是这两个领域不可或缺的基石之一,尤其是对操作系统感兴趣的伙伴可特别关注。
每一次CPU能力的提升带来知识人们更大的贪欲,而且CPU的主频达到4GHz以后很难再向上提升,这个时候唯一的办法就是采取多核策略。
多核的一些基本概念:
在x86体系结构下,多处理功能芯片经过了4个演变阶段,如下所示:
多处理器结构:一条总线上挂载多个处理器。在传统的体系里,一台电脑只有一个CPU;而在多处理器系统里,一台电脑可以有多个CPU,如图所示:
在多CPU的情况下,以CPU之间的关系不同又可以分为对称和非对称多处理器结构。
当然现在SMP结构远比AMP结构普遍。
多个CPU虽然提升了计算机的性能,但是付出的代价是高昂的成本和巨大的功耗。而在实际中,基于很多原因,CPU的执行单元并没有被充分使用。如果CPU不能正常读取数据(由于总线/内存的瓶颈),其执行单元利用率会明显下降。目前大多数执行线程缺乏ILP(Instruction_Level_Parallelism,多种指令同时执行)支持。这些都造成了目前CPU的性能没有得到全部的发挥。因此,Intel提出了超线程(Hyper_Threading)技术来让一个CPU同时执行多个线程,从而提高CPU效率和用户满意度。
超线程技术是在一个CPU上同时执行的多个程序共同分享该CPU内的资源,理论上像两个CPU在同一时间执行两个线程,即可在同一时间里,让应用程序使用芯片的不同部分。超线程结构如图所示:
图中的每个CPU并不是物理上的单个CPU,而是两两为一个独立的CPU。即图中只有4个物理CPU,而每个CPU又因超线程技术被分解为两个逻辑CPU。每个逻辑CPU可以执行一个线程序列。这样一个物理CPU可以同时执行两个线程。
注意:
为了克服多CPU和超线程的缺陷,即实现性能像多CPU,功耗像超线程的结构,这种结构就是多核结构。
多核结构:在一个CPU里面布置两个执行核,即两套执行单元,如ALU、FPU和L2缓存等。而其他部分则两个核共享(由于使用的是一个CPU,其功耗和单CPU一样。由于布置了多个核,其指令级并行将是真正的并行,而不是超线程结构的半并行)。
当然,我们也可以在一台计算机里面布置多个配有多个执行核的CPU,而形成更多的核。如图所示为多核、多处理器结构:
而在多核情况下,我们也可以将超线程技术予以使用,从而形成多核超线程(Multi-core_Hyper_Threading_Architecture)技术。即每个物理执行核里面又分解为两个或多个逻辑执行单元,如图所示:
由于一台计算机里面有多个执行核,而每个执行核均需要对内存进行访问,那么这种情况下内存在多个核之间分配的方式有以下几种:UMA、NUMA、COMA、NORMA
均匀内存访问(UMA):最简单的内存共享方式就是将内存作为与执行核独立的单元构建在核之外,所有的核通过同一总线对内存进行访问。由于每个核使用相同的方式访问内存,其到内存的延迟也相同。在这种模式下,最重要的是所有核的地位在内存面前平等。
当前的对称多处理器共享存储系统基本上采用此种模式。这种模式只能在处理器个数或执行核数从较少时方可使用。
NUMA具有灵活、易扩展的优点,但对调度的要求高。如果不能或难以将程序调度到就近的执行核上,则需要新的机制:缓存。即在每个执行核里面配置缓存,其执行需要的数据均由缓存得到满足。这样,不论数据原来是处于哪个内存单元,其对效率的影响均将不复存在。这种完全由缓冲满足数据访问的模式称为全缓存内存访问,即COMA模式。在这种模式下,每个执行核配备的缓存共同组成全局地址空间。
对于对称多处理器来讲,执行流程如下:
所有的CPU里面有一个被定为启动处理器(Boot_strap_Processor,BSP)。而其他的处理器则作为应用处理器(Application_Processor,AP)。(到底哪个CPU是BSP则由某一特定寄存器的值来决定)
注意:SMP的BIOS与单核或单处理器里的BIOS并不一样。由于有多个处理器,SMP的BIOS里面包括了多个处理器的规格和信息,每个处理器的APIC描述表。而这些信息包括诸如CPU的数量与编号、本地APIC信息、I/O的APIC信息、AP的初始化代码等。
进程间的通信机制如下:管道、套接字、信号、信号量、消息队列、共享内存等。参考这些机制,实现多CPU之间的通信的方式是发送中断,详细说明如下:
在多CPU之间通信,自然也可以发送信号。不过这个信号不是内存的一个对象,因为这样的话,无法及时引起另外一个CPU的注意。而要引起其注意,需要发送的是中断。
用来协调这些CPU之间中断的机制就是所谓的高级可编程中断控制器APIC,这是实现SMP功能必不可少的;且是Intel多处理规范的核心。在此种规范下,每个CPU内部必须内置APIC单元。CPU通过彼此发送中断(所谓的IPI,处理器间中断)来完成它们之间的通信。通过给中断附加动作(action),不同的CPU可以在某种程度上彼此进行控制。
除了每个CPU自己本地的APIC外,所有CPU通常还共享一个I/O_APIC来处理由I/O设备引起的中断,这个I/O_APIC是安装在主板上的。如图所示:描述的是英特尔公司的Xeon多处理器结构下的本地APIC和I/O_APIC的结构示意图。如下所示:
除了处理处理器间及输入输出的中断外,APIC也负责处理本地中断源发出的中断:如本地连接的FO设备、时序中断、性能监视计数器中断、高温中断、内部错误中断等。
由于在对称多处理器结构下,每个处理器都有白己的缓存。这样在一个系统里存在多个缓存的情况下就有可能出现两个缓存的数据不一致的情况。即两个CPU缓存同样的数据,其中一个或两个CPU对数据进行了修改从而造成两个CPU缓存数据的不同。而这有可能造成严艰的后果。因此确保SMP里面的缓存一致性十分重要。而且SMP必须确保对内存地址的访问是最新的数据。
多处理器、超线程和多核的共同点是均为了提升计算机性能而设计、均可以同时执行多个指令序列。但是区别也是明显的,体现在同时执行的两个线程之间共享物理资源的多少。
注意:超线程技术是英特尔公司所独有,其他公司不一定使用这种技术。(例如,AMD公司就直接从多处理器跨越到了多核)