(为解决电子管容易坏的问题,Shockley发明了晶体管。为解决晶体管的集成问题,Kiby发明了集成电路。为了解决Kiby的集成电路飞线的问题,Robert搞出了硅片上沉降金属的集成电路。至此,芯片这个东西已经从无到有被发明出来。)转至知乎
21世纪初,处理器的设计方式发生了巨大的变化。尽管晶体管密度依然增长,但如果仔细分析,会发现很多地方都发生了显著的变化。曾经按照摩尔定律增长的处理器时钟频率开始变得停滞不前,处理器生产商开始从在管芯上设计单核处理器转向多核处理器,通常也被成为多核。从物理的角度看,转向多核设计的原因在于设计更高性能(更深或更宽的流水线)的单核处理器所带来的功耗密度增长无法接受。这也是处理器设计的第二次遭遇功耗的物理限制,第一次遭遇导致处理器设计由双极型晶体管全面转向更高功效的互补金属氧化物半导体CMOS晶体管,而这次暂未出现可以代替CMOS晶体管的功效更高的技术,因此功耗限制需要通过体系结构的改变来解决,即从单核转向多核。
从处理器设计者的角度来看,理论上性能可以通过首先转向多核,之后增加管芯上核心数来保持很长一段时间的增长。但从编程人员的角度来看,转向多核会导致一个很重要的结果:性能的增长依赖于程序员编写并行代码的能力,以及如何调优并行代码使其具有较好的可扩展性。在多核处理器之前,程序员只需关注增加可编程性或者编程抽象的层次。即便这样做会导致代码复杂度的增加以及执行效率的降低,因为他们知道处理器核会变得越来越快从而抵消这些不利影响。然而,现在程序员如果希望克服可编程性和抽象层次增加对性能的不利影响,需要考虑如何利用多核处理器所提供的并行优势来编写程序。并行编程和性能调优对许多程序员而言已经是不可或缺的能力。
本书作者在写作时面临一些重大的挑战。首先,微处理器技术的变化节奏非常快。管芯上核数增加,缓存层次结构越加复杂。其次,多核体系结构有太多主题。
什么是并行多核体系结构?多核体系结构是指在单一管芯上集成多个处理器核core的一种体系结构。处理器核也就是俗称的CPU,通常是指能够独立地从至少一个指令流获取和执行指令的处理单元,因此,核通常包括诸如取指单元、程序计数器、指令调度器、功能单元、寄存器等逻辑单元。
并行体系结构将多个CPU紧密耦合,以便它们一起工作以解决单个问题。受众包括:
1. 公司需要从大量数据库中挖掘数据;
2. 企业依赖于并行计算机上的数据分析和事务处理;
3. 搜索引擎提供商则使用并行计算机对网页进行排序;
3. 游戏玩家要求游戏显式更真实的物理现象模拟和三维图像的真实显示;
多核体系结构是一种较新的设计,仅在微处理器50多年发展历史,21世纪初左右才出现。
2001年以前,并行计算机主要用于服务器和超级计算机,客户机都是单核机器。第一个多核芯片IBM Power 4在2001的上市标志着转折点到来。
是什么导致从单核到多核设计的转变?向多核体系结构过渡的一个有利发展是晶体管的日益小型化,越来越多的晶体管可以封装在单个管芯中,这种晶体管集成的速度是惊人的。
晶体管特征尺寸的减少是管芯上晶体管数量增加的主要因素,其次包括晶体管密度由于更好的布线而增加,再者是更多的管芯区域分配给更密集的结构,如高速缓存。
处理器设计者越来越多地向处理器芯片添加能增强性能的特性以及新的功能。例如Intel 80286中添加的虚拟存储和保护被认为是现代操作系统的关键特性。Intel 386芯片中引入的流水线、集成浮点运算单元、片上高速缓存、动态分支预测等提高微处理器性能的基本技术。Intel Sandy芯片在管芯上集成了图形处理功能。
从1971~2000年,芯片上晶体管的数量增加了18260倍,时钟频率增加18519倍,这意味着大约40%的年增长率。
年度 | 处理器 | 规格 | 新功能 |
1971 | 4004 | 740kHz,2300只晶体管,10um,640B可寻址存储器,4KB程序存储器 | |
1978 | 8086 | 16位,5~10MHz,29000只晶体管,3um,1MB可寻址存储器 | |
1982 | 80286 | 8~12.5MHz | 虚拟存储与保护模式 |
1985 | 386 | 32位,16~33MHz,27.5万只晶体管,4GB可寻址存储器 | 流水线 |
1989 | 486 | 25~100MHz,120万只晶体管 | 集成浮点运算单元FPU |
1993 | Pentium | 60~200MHz | 片上L1高速缓存,支持SMP |
1995 | Pentium Pro | 16KB L1高速缓存,550万只晶体管 | 乱序执行 |
1997 | Pentium MMX | 233~450MHz,32KB L1缓存,450万晶体管 | 动态分支预测,MMX指令集 |
1999 | Pentium III | 450~1400MHz,256KB L1缓存,2800万晶体管 | SSE指令集 |
2000 | Pentium IV | 1.4~3GHz,5500万只晶体管 | 超流水线,SMT |
2006 | Pentium 双核 | 64位,2GHz,1.67亿只晶体管,4MB片上L2高速缓存 | 双核,支持虚拟化 |
2011 | Sandy Bridge i7 | 64位,最高可到3.5GHz,23.7亿只晶体管,最高支持20MB L3高速缓存 | 图形处理器,TurboBoost |
管芯上晶体管数量每1.5~3年翻一倍,一个有趣的问题是:为什么有些功能实现得比其他功能早?首先,晶体管集成度的提高有助于将单个处理器中某些本来不适合于片上的部件集成到芯片中。例如 FPU,之前浮点运算是由协处理器完成的。随着越来越多的晶体管可以集成到芯片上,处理器增加了指令级别开发并行性的功能,比如流水线(Intel 386)、乱序执行(Pentium Pro)和动态预测(Pentium MMX)。由于主存储器的速度跟不上处理器速度的增长,因此有必要引入存储器层次结构,在芯片上集成更小的存储器以实现更快的数据访问。
那么,为什么利用大量晶体管在管芯上集成多个核的进展会“输”给上面讨论的那些进展,比如FPU、Cache、流水线、乱序执行,甚至是向量指令集?事实上,在过去的并行计算机研究中,研究人员很早就考虑过在一个管芯上放置多个核。此外,在多核出现后,管芯还继续集成了多个组件,如内存控制器,三级Cache、加速器、嵌入式DRAM等。
也许可以根据“低挂果”理论来做出适当的解释。如果我们分析出现在多核之前的那些集成在管芯上的组件,会发现它们基本上是单个核的组件,并使用来自单个流的指令来加速单个线程的执行。单个指令流内的并行性不需要程序员或编译器将程序分割成不同的指令流,也不需要程序员改变其编写代码的方式。因此,可以从指令级并行获得的性能改进对于程序员来说在很大程度上是透明的,即使硬件实现可能是复杂的。相比之下,利用多核体系结构来提高性能通常需要并行编程,这需要程序员付出巨大的努力。原因在于大多数高级编程语言将计算表示为一系列程序员已经习惯的操作。因此,为单个程序指定多个指令流需要程序员明确的努力,他们通常必须考虑数据竞争、同步和线程通信等问题。考虑到编程的难度,在其他条件都相同的情况下,微处理器设计者可能会选择用于指令级并行的体系结构技术,而不是多核。
然而,指令级并行性作为“低挂果”逐渐被采摘完毕,从单个核的执行中获得的性能回收开始递减。提高可被处理器利用的指令级并行有2个关键方法:
一是用更多的流水段处理指令,使运行的时钟频率更高(即增加流水线深度);
二是在一个流水段上处理更多指令(即增加流水线宽度)。
当流水线开销变得显著并且关键延迟不受流水线深度影响时,增加流水线深度会遇到效率问题。
能够在一个周期中处理多条指令的处理器被称为超标量处理器。在超标量处理器中增加流水线宽度会遇到复杂性问题,其中处理指令的逻辑电路的复杂性随着流水线宽度增加而以平方量级增加。以Intel Pentium4 Northwood为例,执行指令实际计算的功能单元仅占总管芯面积的5%,而接近90%的管芯面积用来实现确保足够的指令速率和将数据数据传输到功能单元的逻辑。由于大部分管芯被超标量逻辑占用,增加流水线宽度需要管芯上逻辑量近乎平方增长。因此,发展可利用的指令级并行变得越来越困难。
在21世纪头10年,功耗问题付出水面。大约从1971年到20世纪末,指令级并行的开发导致功率密度--即每单位管芯面积消耗的功率--的增加。在2001年以前,功率密度的增加可以通过空气或者增加风扇尺寸冷却处理器来解决。但是,用风冷的散热极限在75W左右,而液冷成本很高以及无法满足外形要求。目前只能改变设计方法,在将越来越多的晶体管封装在单个管芯上的情况下,保持功率密度不变。
在管芯上有静态和动态两种功耗来源。动态功耗有晶体管开关活动引起。静态功耗不是由晶体管开关引起的,而是由通过理想的绝缘体泄露的小电流引起的,此电流被称为泄露电流。
动态功耗至少受电源电压三次方的影响。因此,影响动态功耗的最重要的杠杆可能是晶体管的电源电压。然而,虽然降低电源电压在降低功率密度方面非常有效,但其代价是使逻辑电路变慢以及降低最大时钟频率,除非阈值电压能够充分降低以进行补偿,不幸的是,目前降低阈值电压并不容易,因为我们可能遇到另一个问题:静态功耗。
管芯的静态功耗仅仅是电源电压和泄露电路的乘积。泄露电流随着阈值电压的降低而呈指数增加,但直到20世纪末,静态功耗的幅度都小到足以忽略。21世纪以来,阈值电压无法像特征尺寸那样快速缩减,同时静态功耗限制在可接受的范围限度内。另外,最大时钟频率严重依赖于电源电压和阈值电压之差,所以如果不能按比例降低阈值电压将导致处理器的最大时钟频率突然减慢。自2001年~2005年以来,静态功耗再也不能被忽略,并且随着特征尺寸的继续缩小,阈值电压的降低变得越来越困难。
需要注意的是,与时钟频率增长的停滞相吻合,2001年~2005年正式单核设计放弃选择增加流水线宽度,而向多核设计转变的时期。此时体系结构设计师并没有将相同的工作分割成越来越多的流水段,而是将相同的工作压缩到更少的流水段。
从1985到2001~2005时间段内,体系结构设计师通过将处理器中的指令处理划分为越来越多的流水段来深化流水线。但在2001~2005出现逆转,较高的延迟体现出一个流水段中包含了更多的逻辑工作。然而,因为依赖于指令和指令处理的复杂性,所以流水段的总数可能并不会成比例地减少。
流水线宽度和深度是相关的。处理器核中正在运行的指令总数决定了处理器核的复杂性。执行指令的数量和流水线深度和宽度的乘积成比例。随着流水线深度停止增加,处理器的复杂性随之降低,并且越来越依赖于流水线宽度。然而,由于增加流水线宽度会使处理器核的复杂度呈2次方增长,所以流水线宽度也很困难,也会放慢速度或停滞。
总的来说,自2001~2005以来,作为性能主要增长途径的指令级并行的开发已经在很大程度上减少了,而倾向于多核设计,尽管需要额外的编程工作。直观的问题是多核设计是否比单核设计具有能效更显著的性能改进优势。
假设我们希望将处理器的性能提高一倍。
1.在性能随流水线深度线性增加的理想情况下,将流水线深度加倍。这将需要2倍的电压,处理器的动态功耗增加了8倍。
2.再次假设流水线宽度能够比例地增长性能,将流水线宽度加倍。这将导致许多结构的复杂度(进而功耗)呈二次方增长,动态功耗增加了4倍。
3. 将核数加倍,在性能随核数增加的理想情况下处理器动态功耗会增加1倍。不过核数增加一倍并不能自动提高一倍性能,这取决于程序特性和如何编写并行程序。
程序员经常面临是付出额外的编程代价来获得更好的性能,还是付出更少的编程代价保持不高的性能。以及是选择保守的编译器标志来确保正确性,还是选择会引入不稳定风险的激进的编译器标记以显著提高性能。不只是性能需要考虑,还需要考虑编程的代价和软件的稳定性。因此,处理器设计者选择多核设计而不是持续改进指令级并行是一个冒险的决定,不过这是因为它确信指令级并行将不再提供能效性能提升的空间。
向多核的过渡体现出一些制造商的混合技术中,例如SMT技术允许大量利用为指令级并行而设计的处理器资源实现并行执行。
一个有趣问题是,从指令级并行到多核设计的转换是否有效地解决了“功率墙”问题。
专家认为,功耗问题很可能会一直存在未来若干代微处理器中,并可能随着时间的推移而恶化,甚至创造了暗硅一词,表示由于功率预算不足而导致管芯中越来越多的部分无法接通电源的情况。
多核首次实现了芯片上的并行计算。在多核之前,集群(超算)系统才能执行并行计算。
是什么促使人们使用并行计算机?
1.是与单个处理器系统提供的性能相比,并行计算机能够提供的绝对性能。某些科学发现的速度取决于在计算机上解决特定计算问题的速度。
2. 成本调控的性能或功耗调控的性能方面更具吸引力。多核系统的成本比集群系统相对较小,尤其是软件成本和系统维护方面。
在回顾并行计算机的历史时,应该记住摩尔定律是如何改变处理器体系结构的。并行体系结构最初只是一个自然而然的想法,因为芯片上没有足够的晶体管来实现一个完整的微处理器,因此用这些芯片分别实现处理器的不同组件,或者用它们分别实现不同处理器的组件时,让这些芯片彼此通信就很自然了。最初并行计算机体系结构考虑所有级别的并行性:指令级以及数据并行等。
Almasi和Gottlieb将并行计算机定义为:并行计算机是一系列处理单元的集合,它们通过通信和写作以快速解决一个大的问题。
术语“处理单元”是具有处理一条指令能力的逻辑。它可以是功能单元、处理器上的线程上下文、处理器核、处理器芯片或整个节点。超标量处理器检测指令之间的依赖关系,并尽可能地在不同的功能单元上并行执行独立的指令。同时多线程SMT的核具有多个程序计数器,并且可以执行来自不同线程甚至程序的指令。向量核从单个程序计数器获取指令,但是每个指令可同时处理多个数据项。因此,将处理单元定义为从单个程序计数器提取指令且每个指令对单个数据项集合进行操作的逻辑是有用的。
术语“通信”是指处理单元彼此发送数据。通信机制的选择确定了2类重要的并行体系结构:共享存储系统,在处理单元上进行的并行任务通过读取和写入公共存储空间来通信;或者消息传递系统,所有数据都是本地的,并行任务必须向彼此发送显式消息以传递数据。通信介质(如何使用什么互联网络来连接处理单元)也是确定通信延迟、吞吐量、可扩展性和容错的重要问题。
术语“协作”是指并行任务在执行过程中相对其他任务的同步。同步中重要的问题包括同步粒度(任务同步的时间和频度)以及同步机制(实现同步的操作序列)。这些问题会影响可扩展性和负载均衡属性。
术语“快速解决一个大的问题”表示处理单元共同处理一个问题,其目标是性能。可以选择使用通用或专用体系结构,可以针对特定的计算进行设计和调优,使得机器对于该类型计算能够快速和可扩展性,但是对于其他类型计算则可能较慢。
随着时间的推移,那种类型的并行性更适合跨处理器核或核内实现变得明确。例如,现在指令级并行在核内实现,因为它需要指令之间的寄存器级通信,这可以在核内以低延迟完成。
随着晶体管的不断集成,整个微处理器可放入单个芯片中,单个微处理器的性能迅速提高,这不仅是因为晶体管小型化推动的,这是因为利用指令级并行和高速缓存等大量“低挂果”实现的。从这些体系结构技术获得收益如此之大,以至于单处理器系统可以在几年之内赶上并行计算机的性能。
之前,降低并行计算机相对单处理器系统的优势在于:
1. 大多数应用程序的可实现加速比通常远小于100;
2. 获得加速比往往需要数周到数月的高度手动的并行性能调优;
3. 高度并行系统的市场很小,因此无法从价格占据优势;
4. 设计并行计算机体系结构是一项非常复杂的任务,用于互联处理器以形成紧密耦合的并行计算机的逻辑并不简单。这需要大量额外的开发时间,即当并行计算机开始运行时,其组成部分的处理器往往比现有的最新单处理器慢很多。
低成本分布式计算机是20世纪90年代通过将许多单处理器系统与现成的网络组装而发展起来的。与并行计算机相比,分布式便宜得多,但处理器之间的通信延迟很高。
指令流是单个程序计数器产生的指令序列,数据流是指令操作的存储空间地址。
SIMD以其在执行任务所需指令数方面的高效而著称。SIMD的方式因体系结构而异。在一些GPU中,核以锁步方式来运行执行相同指令的线程,并且该指令对不同的数据进行操作,因此核的作用类似于向量处理器中的向量通道,这种执行模型通常被称为SIMT。多媒体扩展通常不是真正的SIMD,因为不是单个指令对许多数据项进行操作,而是对多个小数据项打包后的单个数据进行操作。
MIMD是最灵活的体系结构,因为其对指令流或数据流的数据每有限制。(尽管与SIMD体系结构相比,它在用于执行单个计算任务的指令数量方面效率较低。)
首先,我们研究MIMD体系结构总处理器是如何物理互联的:
1.选择核共享最后一级高速缓存的一个原因是,最后一级高速缓存时非常重要的资源,其占用管芯上非常大的面积。当所有核共享高速缓存时,可以避免高速缓存的容量碎片。如果某个核处于休眠状态,则活动的核仍可使用共享高速缓存。
2. 选择在专用高速缓存之间提供互联。
a. SMP对称多处理器,不同的处理器共享存储器,并且对存储器具有大致相等的访问时间,于是也被称为UMA体系结构。互联可以利用总线、环、交叉开关或点对点网络。如今,SMP可以用多核芯片作为构建块来搭建。许多目标用于服务器的多核芯片已经在管芯上包含了路由器,以将芯片连接到其他芯片,从而创建由若干芯片组成的大型共享存储器系统。
b.是每个处理器都有私有的高速缓存和本地存储器的体系结构,但是硬件提供跨越所有本地存储器的互连以给出单个存储器的抽象。然而,由于远端存储的访问时间比本地存储长,因此存储器访问的延迟会有所不同,也被称为NUMA或分布式共享存储。
c.每个处理器都是一个完整的节点,具有自己的高速缓存、本地存储和磁盘;并且通过IO连接提供互联。因为IO连接的延迟很大,所以硬件可能不会提供单个存储器的抽象,于是被称为分布式计算机系统或集群。集群为那些不需要再进程或线程之间进行低延迟通信的计算提供并行计算平台。
无论未来的体系结构是什么,它将取决于不断评估的下一个可以摘到的“低挂果”。做出预测的最简单的办法是预测趋势的延续。多核真的会以每18个月翻倍么?反对的原因在于:
1. 促使设计者从指令级并行的单核设计转向多核设计的原因:“低挂果”的逐渐消失。并行编程已被证明对于具有相对规则的代码结构的程序,或者算法对大量数据项应用相同(近似)计算的程序,其是有效的。并行编程对于具有复杂代码的结构,并且在大量数据项上不执行相同的计算的程序并未显示出有效性。由于各种原因,它们在超过数百个核加速比通常不会线性扩展。加速比在100核之前就会停滞,然后下降,拥有更多核的边界收益就很小。
2. 增加更多的核需要以超线性方式填充支撑它们的基础组件。核数增加一倍,主存储器的数据带宽需要增加一倍,以实现平衡设计。由于各种原因,如功耗和对扩展芯片针脚数量限制,很难快速增加片外带宽。为了避免数据带宽需求的快速增加,可以增加管芯上高速缓存容量以过滤或降低必须从片外存储器获取数据的频率。经验法则,必须将高速缓存大小增加4倍,才能将其缺失降低50%。这种策略要求为高速缓存分配越来越多的管芯,而为处理器核分配越来越少的管芯,这反过来又限制管芯面积的增加。
3. 即使能够非常成功地利用多核中的并行性,执行中的非并行部分也将日益成为瓶颈。另外,负载均衡、同步开销、通信开销和线程管理开销同样限制了并行程序的性能。如Amdahl暗示,随着并行化的进行,非并行部分和并行开销的相对重要性不断增加。
4. 功率墙问题。必须采用晶体管数量增加时降低功率密度的技术。换句话说,未来微处理器必须提高能效。
以上讨论了传统多核设计中增加核数的几个限制因素:用于提高性能的“低挂果”逐渐消失、支持更多核所需的成本日益高昂的基础组件、执行时间中非并行部分重要性的日益增加,以及功率密度的不断恶化使得未来体系结构中需要提高能效等。
与简单地增加核的数量相比,
1.专用加速器可以以更节能的方式改进性能。因此,加速器可能越来越多地集成在管芯上。
2.用晶体管将系统的其他组件集成到管芯上,如IO控制器、图形引擎和部分主存储器。
3. 引入异构性,即可以在管芯上添加具有多种性能和功率特性的核。可以选择实现了最佳功率-性能折中的核来执行不同的程序或程序段,同时关闭其他核。例如,强大的大核加速非并行执行,众多小核可用于执行高扩展性程序,而中等大小的核可用于执行中等扩展性程序。
为了支持更多的核,可能会越来越重视更大,更复杂和更优化的存储器层次结构、片上网络、内存控制器体系结构,以支持核数的增加。未来多核体系结构可能会变得更加多样化、更加复杂、其管理也更加精细。
除了功率墙之外,多核体系结构设计还面临的其他挑战之一是片外带宽。在传统非多核的多处理器系统中,增加更多的处理器通常涉及增加更多的节点,并且因为节点由处理器及其存储器组成,所以主存储器的聚合带宽将会随着更多的处理器而增加。相反的情况发生多核系统中,核数增加并没有增加主存储器的聚合带宽。因此,除非片外带宽能够以与多核中的核数相同的速度扩展,否则每个核的可用片外带宽将下降,这潜在地导致多核性能受“带宽墙”的影响。
未来影响带宽墙问题严重性的因素:
1. 提供更高的片外带宽是昂贵的;可能需要分配更多的互连针脚,以及更高的时钟频率运行片外接口。这二者都会导致片外通信的更高功耗。恶化了功率墙问题,限制管芯的核数增长。
2. 如果多核性能得到显著提高,那么带宽墙问题更糟。其中一个解决路线是堆叠DRAM。通过将DRAM和逻辑堆叠在一起,堆叠的DRAM的带宽将比片外存储器的带宽高很多。
与功率墙相比,带宽墙的问题的严重性稍逊一筹。在不缓解带宽墙的问题下,管芯上核数仍然可以保持增长,但是其速率小于晶体管密度的增长。其原因在于,通过减缓核数的增长,仍然可以将更多管芯用于高速缓存,这些高速缓存可以用来过滤与片外存储器的数据通信。因此,有效减缓核数的增长减轻了“带宽墙”的问题。