1.4 计算机体系结构
计算机组成处理的是计算机的各个部件的操作问题,而计算机体系结构处理的是计算机的算术运算模块(例如,加法器和乘法器)和指令系统的设计,也涉及计算机系统性能提升的相关问题,包括实现在每秒钟内执行更多指令、减少程序的整体运行时间和执行更多的任务的方法。
1.4.1 流水线
流水线的概念与分级装配零件以便在更短的时间内生产出更多产品(例如汽车)的工厂装配线相似。图1-9的表格展示了一个简化的三级汽车装配线的工作过程。如图所示,当装配线满负荷时(每一级都有一辆汽车在组装),每10分钟就有一辆汽车产出(假设装配一辆车需要耗时30分钟:10分钟安装发动机,10分钟安装车门,10分钟安装车轮)。装配线上的级数越多,且每一级的延时越短,生产的汽车就越多。例如,假设装配线可以分解成多个简单段,每段只需2分钟完成(即时隙为2分钟)。在本例中,理想的情况下,一年内可以生产出超过260?000辆汽车,每2分钟有一辆车产出。
在设计CPU时,流水线概念用于将CPU的数据通路组织成多级,以便提高程序运行速度。考虑程序中的语句“A = B + C;”,其等价的汇编语言程序如下:
图1-10中的表格展示了在由3个流水级构成的数据通路中4条指令的执行情况:
取指级:从内存中读取下一条指令。
译码级:生成数据通路的控制信号。
执行级:执行指令。
在时钟周期T = 1时,从内存中取出(读出)指令“Load R1,B”;T = 2时,Load指令正在译码级被译码,而指令“Load R2,C”被从内存中取出。T = 3时,指令“Load R1,B”正在执行,而指令“Load R2,C”正在被译码,“Add R3,R1,R2”指令正在取指。从T = 3开始,流水线被填满,且全部三级都处于忙状态,从时钟周期3到时钟周期6,每个时钟周期都有一条指令被执行,正如图中所示。每一条指令仍然需要三个时钟周期才能执行完,但不同指令的取指、译码和执行任务可以重叠并同时完成。三级流水数据通路由取指、译码和执行这三个独立的数据通路组成。
一般而言,虽然流水CPU比非流水CPU每秒可以执行更多的指令,但是分支和访存时间可能会延迟某些指令的执行。
浮点单元
流水线的概念也应用于复杂的算术运算模块,例如对浮点数进行操作的浮点运算单元(FPU)。浮点指令的执行需要多次算术运算和移位操作,而如果这些操作以流水方式执行,程序将会执行更快。例如,考虑以下对浮点数组进行操作的for循环语句:
for循环执行100次浮点加法指令。使用流水CPU,这100条指令需要大约100个时钟周期完成。这减少了执行for循环的总时间,虽然每次执行浮点加法指令实际上都需要多个时钟周期来完成,第3章中将会详细讨论。在本例中,图1-10中所示的执行级本身将由多个流水级构成。
1.4.2 并行性
当任务相互依赖时可以采用流水线技术,例如执行指令所需的取指、译码和执行任务。另一方面,当任务相互独立且可以并行执行时则可以采用并行技术。并且,流水线技术和并行技术都要求高可用性的输入和快速的输出处理。只有当工厂装配线高效运行、必需的部件及时到达且最后成品能被快速运走时,这个工厂才能在更短的时间内生产出更多的产品。这类似于数据和指令被快速地从内存传送到处理器并且计算结果被快速存入内存。为了实现这一目标,需要用高速(cache)存储器保存最近使用的指令和数据以实现快速存取,并用低速且大容量的廉价存储器保存不同的程序和数据。
下列各小节将简要介绍应用于CPU、处理器和系统设计的并行技术。
1.单指令多数据流
得益于IC技术的发展,芯片上可用的晶体管数量不断增加,现代处理器开始包含可以在多个数据项上并行操作的特殊指令,从而提升了性能[5]。此类指令的一个例子是应用于英特尔处理器的单指令多数据流(SIMD)扩展(SSE)指令系统,或者应用在AMD处理器上的3DNow指令[6, 7]。
在许多应用领域中,例如计算机游戏,需要通过多次算术运算来生成单一的结果。一个虚拟游戏对象通常包含上千个数据点,称为顶点。在计算机屏幕上移动虚拟游戏对象需要重定位该对象的每一个顶点,采用的是一种称为顶点转换的技术。每次顶点转换都需要若干次乘法和加法运算来确定顶点的坐标位置和对象的旋转角度,使用的是将会在第6章中介绍的二维(2-D)坐标旋转数字计算机(CORDIC)的旋转算法。2-D CORDIC旋转流水数据通路的设计和仿真也将在第6章讨论。
图1-11展示了包含4个乘法器SIMD数据通路,可以并行生成4个乘积项。在SIMD架构下,单个指令可以在多个数据项上进行操作,从而缩短了单个顶点转换所需的总时间。利用通常在GPU中常用的多SIMD执行单元技术,可以制作更具真实感的视频游戏。
通常,在诸如奔腾4之类的通用处理器中采用的SIMD技术仅限于支持有限的数据项,这对更先进的游戏来说是不够的。另一方面,GPU则包含类似的更专用的数据通路以提升性能。
2.指令级并行
随着集成电路上可用的晶体管数量的增长,计算机性能的进一步提升要求并行(即同时)执行多条指令。在这种情况下,CPU的数据通路将设计成从内存一次取出多条指令、译码多条指令并同时执行多条相互独立的指令[8]。
确定相互独立的指令序列可以由处理器内部的硬件动态实现(例如英特尔酷睿i7),也可以由编译器静态实现(例如英特尔基于安腾的系统)。运行于基于安腾的系统上程序所含的汇编指令由编译器组织成指令束,每个指令束最多包含三条独立指令。处理器并行地取指、译码和执行每个指令束中的指令。不过,现有的程序必须被重新编译才能利用安腾数据通路的优势,许多人相信这是其没落的原因。
图1-12展示了包含于一个静态生成的指令束的三条指令的指令级并行(ILP)执行过程。在每个时钟周期中,三条指令被取指、译码和执行。首先,I0至I2三条指令被取指,然后当这三条指令被译码时,下三条指令I3至I5被取指。从第3个时钟周期开始,9条指令被并发处理。然而,一个程序中多条指令间的数据
依赖关系使得可用的硬件资源得不到最充分的利用。
对各个基准测试程序的研究表明只有有限数量的独立指令可以同时并行执行[9]。因此,这导致了一个限制,即到底多少个晶体管能被用于高效执行单一程序,并在执行程序时充分利用可用的硬件。因此,随着晶体管数量的不断增加,设计师并不能用过多的晶体管进一步提升处理器核的效率。有时,一个处理器核被设计为可同时运行多个(例如两个)程序以提升效率,称为多线程。更进一步,充分利用不断增长的晶体管数量的一个普遍做法是在单芯片上实现多个相同的处理核,从而构成多核处理器。ILP和多线程体系结构将在第8章中讨论。
3.多核处理器
图1-13展示了一个四核处理器的结构。其中的每个处理器核都可以执行一个或少量的程序,每个程序称为一个线程,从而让多核处理器可以同时执行多个任务。由于在任何特定的时间点,每个处理器核都可能执行不同的指令并操作不同的数据项,因此多核处理器被认为采用了多指令多数据(MIMD)结构[5]。回忆一下单条SIMD指令同时操作多个数据项的情况。同样,单指令单数据(SISD)这一术语定义了一种单核执行非SIMD指令的结构;然而,ILP可以被用于加速SISD的执行。
图1-13同时也展示了一种共享存储器系统的结构。在此例中,为了更快地运行程序,程序员需要创建多个程序线程,这被称为多线程编程,方法是将程序中的数据结构在多个线程之间分割,而这些线程可以并行或并发地在多核处理器上执行,或者概括而言,在一个共享存储器的多处理器系统中运行。每个线程需要操作程序数据的子集,并与其他线程进行同步和通信。一个线程可以访问其自身的局部变量,而在多线程程序中的所有线程可以共享并操作全局声明的变量。而且,这些核可以执行不同程序的线程。
其他类型的多核处理器包含由不同复杂度的核构成的异构多核,以便支持不同应用的处理需求[10]。例如,一个ILP核可以用于时序计算,而一个大型SIMD核可以用于并行地对大量数据项进行操作,适合也需要数据并行计算的应用。可以预见,同时需要时序和数据并行计算的应用在异构多核处理器上运行得比在同构多核处理器上要快。处理器往往使用多级cache存储器(如图1-2所示)来促进快速片上指令和数据访问,并在不同核间共享数据。
图1-14为第4代四核英特尔i7处理器的结构图,每个核拥有二级cache存储器(图中未显示)和L3共享cache存储器,以及一个图形处理器。
然而,随着片上晶体管数量及其转换速度的提高,持续的电源消耗总量和散热量也会增加。这限制了单个处理器上可以容纳的核的数量。电力和散热需求可以用称作热设计功率的指标度量,其中可以用于更好地平衡电源消耗和散热需求的方法有多种,例如动态降低晶体管转换速度(即时钟频率)。这些方法虽然有时可以提升处理器的性能,但是如果想进一步提升性能还需要用多个处理器(每一个处理器都可以是多核)来构造多处理器系统。
4.多处理器系统
多处理器系统可以采用共享存储器机制或者消息传递机制。在共享存储器多处理器系统中,操作系统要有“线程感知”能力以便每个线程都能快速地访问其局部变量。然而在消息传递系统中,线程必须通过发送和接收信息来进行通信,在消息传递系统中线程没有可访问的共享变量。
多处理器系统可以并行和并发地执行多个线程。因此这种工作方式提高了系统的吞吐量,即系统在单位时间内可以执行的任务数。运行一个科学应用(例如仿真海浪)所必须具备的每秒浮点运算次数(FLOPS),或者在差不多几秒钟的一小段时间内系统能够处理的谷歌搜索次数,都是系统吞吐量的实例。这些系统通常使用大量存储器并在各个单独的处理器之间或者互联的处理器组之间分区使用。
图1-15展示了有三个节点的共享存储器多处理器系统结构图。在此例中,每个节点都由一个双核处理器、存储器和一个节点间通信接口组成。每个核都可以访问M0、M1和M2存储器。共享存储器多处理器系统被用于各种服务器的设计。
另一方面,多个网络系统可以构造成一个消息传递多处理器系统,其中的每一个网络系统可以是单处理器系统或者服务器节点。节点组成集群,并以通过网络发送和接收消息的方式进行通信。最后,仓库规模计算机是由数千台服务器构成的集群。有些仓库规模的计算机被当作现代超级计算机系统用于科学计算,要求非常高的FLOPS指标。
集群和仓库规模计算机提供了可用性(如果一台服务器崩溃,其他的服务器还能继续工作)、交互式应用(例如在线购物、谷歌、Facebook、电子银行等)和大规模存储与计算(例如云计算)。电力分布和散热问题是当前超大型计算系统设计师面临的挑战。多核和共享存储器多处理器系统将在第10章中进一步讨论。