《新的体系结构.doc》由会员分享,可在线阅读,更多相关《新的体系结构.doc(16页珍藏版)》请在三一办公上搜索。
1、10第 章 新的体系结构在台式计算机的微处理器设计方面的最新进展包括将多个处理器放置到一个计算机芯片上。这些多核设计完全取代了作为台式计算机的基础的单核设计。IBM、Sun、Intel和AMD都已经将他们的芯片流水线从生产单核处理器变为生产多核处理器。这已经促使计算机供应商将他们的重心转移到销售拥有多核的台式计算机,如Dell、HP和Apple。在这个新的领域的市场份额的竞争中,每个计算机芯片生产商都在挑战着能够经济地放置到一个芯片上的内核数目的极限。所有这些竞争使得消费者拥有了比以前更多的计算能力。主要的问题在于常规的台式计算机软件没有被设计为利用新的多核架构。实际上,为了能够从新的多核体系
2、结构中得到任何真正的加速,将必须重新设计台式计算机软件。设计和实现利用多核处理器的应用软件的技术,和在单核开发中使用的技术有着根本的区别。软件设计和开发的焦点将必须从顺序编程技术转变为并行和多线程编程技术。现在,一般开发人员的工作站以及入门级的服务器都采用具有硬件级多线程、多处理和并行处理能力的多处理器。尽管顺序编程和单核应用开发仍将保留有一席之地,但是多核应用程序设计和开发的思想现在已经成为主流。本章将会带您了解多核编程,介绍的内容有: 什么是多核? 有哪些多核体系结构以及它们之间有什么区别? 作为软件的设计人员和开发人员,当从顺序编程和单核应用开发转移到多核编程时,需要知道哪些知识?1.1
3、 什么是多核多核是一种将多个处理器放置到一个计算机芯片上的架构设计。每个处理器被称作一个核。随着芯片容量的增加,在一个芯片上放置多个处理器变得可行。这些设计被称为芯片多处理器(Chip Multiprocessor,CMP),是因为它们允许单芯片进行多处理。多核是CMP或单芯片多处理器的流行的名字。单芯片多处理的概念并不是新的,早在20世纪90年代初期,芯片生产商就已经开始探索在单芯片上放置多个内核的想法。最近,CMP已经成为改进总体系统性能的首选方法。这种方法与通过增加时钟频率或处理器速度来获得总体系统性能收益是截然不同的。增加时钟频率的方法已经开始在成本效益方面达到其极限了。较高的频率要求
4、更多的能耗,使得系统制冷变得困难且代价高昂。这还会影响确定尺寸和封装(sizing and packaging)方面的考虑。所以,现在的做法是增加更多的处理器,而不是令处理器运行得更快以获得性能上的提升。由于这种方法实现简单,因此是更好的方法,所以该方法驱动了多核革命。当前,多核体系结构在增强总体系统性能方面成为了焦点。对于熟悉多处理的软件开发人员,对多核开发应当也不陌生。从逻辑的观点,对分开封装的多个处理器进行编程与对包含在单独芯片上的单个封装上的多个处理器进行编程,两者之间并没有很大的区别。当然可能会存在性能差异,因为新的CMP利用了总线体系结构以及处理器之间连接等方面的进步。在某些环境下
5、,这可能会使得原本为多个处理器编写的程序能够在CMP上更快地执行。除了潜在的性能收益,设计和实现都是非常类似的。在本书中,我们将讨论其中存在的微小差别。对于只熟悉顺序编程和单核开发的开发人员,多核方法提供了很多新的软件开发范型。1.2 多核体系结构CMP有多种形式:两个处理器(双核)、四个处理器(四核)和八个处理器(八核)结构。有些结构是多线程,有些结构不是。在新的CMP中,高速缓冲存储器(cache)和内存的处理方式有着几种变体,在不同的实现中,处理器与处理器之间的通信方法也不同。来自各大主要芯片生产商的CMP实现中,在处理I/O总线和前端总线(Front Side Bus,FSB)上均不相
6、同。如果严格地从逻辑视图上查看被设计为利用多核体系结构的应用程序时,并看不出大多数区别。图1-1示范了支持多处理的3种常见配置。图1-1 图1-1中的配置1使用超线程(hyperthreading)。与CMP类似,使用超线程的处理器允许在一个芯片上执行两个或多个线程。然而,在超线程的封装中,多个处理器指的是逻辑上的,而不是物理上的。这些封装中有着两套硬件,但是不足以构成一个单独的物理处理器。这样,超线程允许处理器在将自身呈现给操作系统时,好像是完备的多处理器,但实际上只是在一个处理器上运行多个线程。 图1-1中的配置2是经典的多处理器。在配置2中,每个处理器位于一个独立的芯片上,而且有着自己的
7、硬件。 配置3代表了当前多处理器的发展趋势,它在一个芯片上提供完整的多个处理器。如同您将在第2章所看到的,一些多核设计在核的内部支持超线程。例如,一个使用了超线程技术的双核处理器可以将自己作为四核处理器呈现给操作系统。混合型多核体系结构混合型多核体系结构(hybrid multicore architecture)在一个封装中混合了多种处理器类型和/或线程模式。这样能够通过将多种独特的性能合并到一个功能内核中,提供有效的代码优化和特化(specialization)的方法。混合型多核架构的最常见示例是IBM的Cell broadband engine(Cell)。我们将在下一章中介绍Cell的
8、体系结构。需要注意的是每种配置是作为由两个或更多个能够并发执行多个任务的一组逻辑处理器来呈现给开发人员的。对系统程序员、内核程序员和应用程序开发人员的挑战是需要了解何时以及如何利用这一点。1.3 软件开发人员眼中的多核体系结构CMP的低成本和广泛可用性,使得一般的软件开发人员能够进行各种级别的并行处理。并行处理不再是超级计算机或集群的专属领域。基本的开发工作站和入门级服务器现在都具有软件级和硬件级的并行处理能力。这意味着程序员和软件开发人员可以无需牺牲设计或性能,即可根据需要部署利用多处理和多线程的应用。然而,需要注意的是,并非每个软件应用都需要多处理或多线程。实际上,一些软件解决方案和计算机
9、算法最好使用顺序编程技术来实现。在某些情况下,在软件中引入并行编程技术的开销会使软件性能降级。并行性和多处理是需要一定成本的。如果软件中顺序地解决问题需要的工作量少于创建额外线程和进程的开销,或者少于协调并发执行的任务之间通信的工作,则应选择顺序的方法。有时可以较容易地确定何时及何地应当使用并行性,因为软件解决方案本身可能会要求支持并行性。例如在很多客户端服务器配置中,很显然是需要并行性的。可能有一个服务器,例如数据库,还有很多可以同时对数据库发起请求的客户端。在多数情况下,您不希望一个客户端被要求等待,直到另外一个客户端的请求被满足。可接受的解决方案允许软件并发地处理客户端的请求。另一方面,
10、有时候可能会在不需要并行性时面对并行性的诱惑。例如,您可能会倾向于相信在文本中进行并行关键字搜索理所当然地比顺序搜索快,但是这依赖于需要搜索的文本的规模,同时还依赖于启动多个并行搜索agent所需要的时间和开销数量。设计决策者若赞成使用并发的解决方案,则必须考虑盈亏临界点和问题规模。在多数情况下,软件设计和软件实现是分开进行的,而且很多时候是由不同的小组来执行的。但是当主要的系统需求是软件加速或性能优化时,软件设计小组必须至少清楚软件实现的选择,而软件实现选择必须知道潜在的目标平台。在本书中,目标平台是多核平台。为了充分利用多核平台,您需要理解做些什么工作才能获得CMP的性能。您需要理解CMP
11、中的哪些部分是可以控制的。您将看到可以通过编译器、操作系统调用/库、语言特性、应用程序级库来访问CMP。但首先,为了理解如何处理CMP访问,需要对处理器体系结构有基本的理解。1.3.1 基本的处理器体系结构您可以访问和影响的部件包括寄存器、主存储器、虚拟内存、指令集使用以及目标代码优化。在试图与多处理器体系结构打交道之前,理解在单处理器架构中可以影响哪些部件非常重要。图1-2给出了简化的处理器架构和内存部件的逻辑概览。图1-2处理器架构有很多变体,图1-2只是一个逻辑概览。它说明了您可以使用的主要处理器部件。尽管这个级别的细节和这些部件对特定类型的应用程序开发经常是透明的,但是它们在自底向上多
12、核编程和以加速和性能优化为主要目的的软件开发中都发挥着核心作用。与处理器的主要接口是编译器。操作系统是二级接口。注意:在本书中,我们将使用C+编译器来生成目标代码。并行编程可用于使用多种方法的所有类型的应用程序,从低级到高级,从面向对象到结构化应用程序。C+支持多范型编程方法,因为其拥有较强灵活性,所以我们会选择使用它。表1-1给出了编译器与CPU和指令集交互的类别清单。包括浮点类别、寄存器操纵类别和内存模型类别。表1-1 编译器开关选项描 述使用的示例Vectorization这个选项将激活vectorizer,它是编译器中的一个组件,自动在MMX寄存器中使用单指令多数据(Single In
13、struction Multiple Data,SIMD)指令以及所有SSE指令集-x -ax激活vectorizerAuto parallelization这个选项识别包含并行性的循环结构,然后(如果可能)安全生成并行执行的多线程等价体-parallel触发自动并行化Parallelization with OpenMP使用这个选项,编译器基于程序员在源码中加入的OpenMP指示来生成多线程代码#pragma omp parallel#pragma omp for/your codeFast这个选项用于检测不兼容的处理器,在执行中生成错误消息-O1为代码规模和代码局部性进行优化,并禁用循环展
14、开、软件流水和全局代码调度-O2默认值,将软件流水置为ONFloating point允许编译器影响对浮点指令的选择和使用的一组开关-fschedule-insns告诉编译器可以发送其他指令,直到要求一个浮点指令的结果为止-float-store告诉编译器在生成目标代码时不使用在寄存器中存放浮点变量的指令(续表) 编译器开关选项描 述使 用 实 例Loop unrolling这个选项用于激活循环展开;它只应用于编译器被确定为应当被展开的循环;如果将n省略,则由编译器决定是否进行展开-unroll激活循环展开,设置循环展开的最大次数n=0禁用循环展开,仅为64位架构下的容许值Memory ban
15、dwidth这个选项用于激活或禁用对处理器使用的内存带宽的控制;如果禁用,则带宽会在多个线程间完全共享;可以和auto parallelization选项一同使用;这个选项仅用于64位架构-opt-mem-bandwidthn=2为并行代码(如pthreads和MPI代码)激活编译器优化n=1为编译器生成的多线程代码激活编译器优化Code generation使用这个选项代码,为特定架构或处理器进行代码优化;如果有性能收益,编译器生成多条、处理器特定的代码路径;用于32位及64位架构-ax为指定处理器生成优化代码-axS使用SIMD Extensions 4(SSE4)向量编译器和媒体加速器指
16、令生成专门的代码路径Thread checking这个选项激活使用线程的应用程序或程序中的线程分析,只能和Intel的Thread Checker工具一同使用-tcheck激活使用线程的应用程序或程序的分析Thread library这个选项使得编译器包含来自Thread Library的代码;程序员需要在源代码中包含API调用-pthread针对多线程支持使用pthread库1.3.2 CPU(指令集)CPU有着它识别并执行的原生指令集(native instruction set)。C+编译器的工作是将C+程序代码转换到目标平台的原生指令集。编译器对C+进行转换并生成一个由目标处理器的原生
17、指令组成的目标文件。图1-3显示了基本编译过程的缩略图。图1-3在将C+代码转换为目标CPU本地语言的过程中,编译器可以选择如何生成目标代码。编译器可用来帮助确定寄存器如何使用或是否执行循环展开。可以通过对编译器选项的设置来决定是否生成16位、32位或64位目标代码。编译器可用于选择内存模型。编译器可以提供代码提示来声明提供多少L1(level 1) cache或L2(level 2) cache。注意在表1-1中的浮点操作类别中,该类别中的开关允许编译器影响对浮点指令的选择。例如,GNU gcc编译器有- -float-store开关。这个开关告诉编译器在生成目标代码时,不应当使用将在寄存器
18、中存储浮点变量的指令。Sun C+编译器有-fma开关,这个开关允许自动生成浮点和multi-add指令。-fma=none禁用了这些指令的生成。-fma=fused开关允许编译器通过使用浮点、fused和multiply=add指令来尝试改进代码性能。在上述两种情况下,开关都作为选项提供给编译器:gcc ffloat-store my_program.cc或CC fma=used my_program.cc其他开关影响cache使用。例如Sun C+编译器有-xcache=c,定义了被优化器使用的cache属性。GNU gcc编译器有-Funroll -loops,指定循环如何展开。GNU
19、gcc编译器的-pthread开关开启了对使用pthread的多线程的支持。编译器甚至还有选项可用来设置典型内存引用间隔,使用的是-mmemory-latency=time开关。实际上,对于图1-2中的任何部件,均有编译器选项和开关可影响它们的使用。编译器提供对处理器的访问,对为特定目标处理器或处理器系列编写多核应用程序的开发人员是有影响的。例如,UltraSparc、Opteron、Intel Core 2 Duo和Cell处理器都是常用的多核配置。这些处理器均支持高速向量操作和计算。它们支持并行计算的单指令多数据(SIMD)模型。这种支持可以通过编译器来获得,并受编译器影响。注意:第4章包
20、含了对编译器在多核开发中的作用的详细介绍。值得注意的是,使用过多这种类型的编译器选项,会导致编译器为特定处理器进行代码优化。如果设计目标之一是跨平台兼容,那么必须小心使用编译器选项。对于系统程序员、库制作人员、编译器编写人员、内核开发人员、数据库和服务器引擎开发人员,对基本处理器架构、指令集和编译器接口的基本理解是开发利用CMP的有效软件的先决条件。1.3.3 内存是关键事实上,在计算机系统中发生的所有事情都是要经过某种内存的。多数事情需要经过很多的内存级别。软件及同它关联的数据在执行之前通常存储在某些外部介质中(通常为硬盘、CD-ROM、DVD等)。例如,假定您有一个非常重要且非常长的数字列
21、表存放在一个光盘中,而且需要将这些数加到一起。同时假定用来对这个非常长的数字列表进行累加的程序也保存在光盘中。图1-4说明了程序和数据如何流向处理器。图1-4在不同类型的内存中,您必须记住的是典型的CPU仅对保存在其寄存器中的数据进行操作,它没有直接访问存储在其他位置的数据或程序的能力。图1-4显示了ALU对寄存器的读取和写入,这是正常的状况。指令集命令(处理器的本地语言)被设计为主要针对CPU寄存器中的数据或指令进行工作。为了将您的重要的数字列表和程序取到处理器,必须从光盘中提取软件和数据并加载到主存储器中。从主存储器开始,软件和数据被传递到L2 cache,然后到L1 cache,接下来传
22、递到指令和数据寄存器,这样CPU可以进行它的工作。值得注意的是在每个阶段,存储器的执行速度是不同的。二级存储器,如CD-ROM、DVD和硬盘的速度要低于主随机存取内存(random access memory,RAM)。RAM的速度慢于L2 cache内存。L2 cache内存慢于L1 cache内存。处理器中的寄存器是您能够直接打交道的速度最快的存储器。各种类型的存储器除了在速度方面有区别外,规模也是一个因素。图1-5给出了分级存储器体系(memory hierarchy)的概览。图1-5寄存器的速度最快,但是容量最小。例如,一台64位计算机通常有一组寄存器,每个寄存器能够保存最多64比特。
23、在某些实例中,寄存器可以成对使用,允许保存128比特。在容量方面,紧随寄存器之后的是L1 cache和L2 cache。L2 cache目前是以MB为单位进行度量的。从L2 cache到系统主存,在最大容量方面有一个巨大的提升,系统主存的容量当前是以GB为单位进行度量的。除了各种类型的存储器的速度以及容量之外,还有一个因素是各类存储器之间的连接。这些连接被证明对总体系统性能有着重要的影响。在二级存储器中保存的数据和指令必须通过I/O通道或总线才能到达RAM。一旦到达RAM,数据或指令通常经由系统总线到达L1 cache。I/O总线以及系统总线的速度和容量在多处理器环境中可能会成为瓶颈。随着芯片
24、上内核的数目的增加,总线架构以及数据通路的性能带来的影响就更加明显。本章稍后部分将讨论总线连接,首先我们来了解分级存储器体系以及它在多核应用程序开发中扮演的角色。要记住,就像您可以使用编译器对指令集选择的影响那样,您也可以使用编译器来操纵寄存器使用和RAM对象布局、提供cache规模提示,等等。您可以使用更多的C+语言元素来指定寄存器使用、RAM和I/O。这样,在您详细了解多处理和多线程之前,必须对处理器处理的分级存储器体系有基本的了解。1.3.4 寄存器寄存器是用于特殊目的的、规模小但速度快的存储器,可以被内核直接存取。寄存器是易失的(volatile)。当程序退出时,程序在寄存器中用于任何
25、意图和目的的任何数据或指令都会消失。与交换内存、虚拟内存不同,这些内存是持久的,因为保存在某种二级存储器中,而寄存器是暂时的。寄存器中的数据只在系统加电或程序运行期间保持。在通用计算机中,寄存器位于处理器内部,因为几乎为零延迟。表1-2包含了多数通用处理器中的寄存器的常见类型。表1-2寄 存 器描 述Index在通用计算中以及处理地址的特殊用法中使用Segment用于保存地址的段部分IP用于保存下一条要执行的指令的地址偏移部分Counter用于循环结构,但也可用于通用计算用途Base用于地址的计算和存放Data用作通用寄存器,而且可用于临时存储和计算Flag显示计算机状态或处理器状态Float
26、ing point用于计算和移动浮点数多数C/C+编译器有着可以影响寄存器使用的开关。除了能够用于影响寄存器使用的编译器选项外,C+还有asm 指示符,它允许在C+的过程或函数中写入汇编语言,例如:void my_fast_calculation(void).asm.mov 2 , %r3inc(%r3).my_fast_calculation( )将2加载到UltraSparc处理器的%r3通用寄存器中。尽管对于C+,cache不是轻易可见的,但是寄存器和RAM是可见的。根据开发的多处理器软件的类型,无论是通过编译器还是通过C+ asm 指示符,对寄存器的操纵是必要的。1.3.5 cache
27、cache是位于处理器和主系统内存(RAM)之间的存储器。尽管cache不像寄存器那样快,但是仍要快于RAM。它的容量大于寄存器,但是小于主存。cache增加了有效的存储器传递速度,因此提高了处理器总体性能。cache用于保存处理器最近使用的数据或指令的副本。会从主存中获取小的内存块并保存到cache中,期望处理器会需要它们。程序具有时间局部性(temporal locality)和空间局部性(spatial locality)的倾向。 时间局部性是重用最近访问的指令或数据的倾向。 空间局部性是访问物理上接近于最近访问项的指令或数据的倾向。cache的一项主要功能是利用程序的这种空间局部性和时
28、间局部性的特性。cache通常会被分为两个级别,即level 1和level 2。注意:cache的完整讨论超出了本书的范围。若需要了解关于cache的详细讨论,可参考Hennessy,Patterson,2007。1. level 1 cachelevel 1 cache的规模较小,有时候只有16KB。L1 cache通常位于处理器内部,用于截获最近使用的指令或数据的字节。2. level 2 cache同L1 cache相比,level 2 cache要大一些,但速度要慢些。当前,它位于主板上(处理器外部),但是这一点正在逐渐变化。当前,L2 cache通常以MB为度量单位。L2 cach
29、e可以保存更大块的最近使用的指令、数据和邻近L1 cache保存内容的项。由于L1和L2快于通用RAM,因此对程序接下来要做的事情猜测得越正确,则总体系统性能越好,因为正确的数据块将位于L1 cache或L2 cache中。这样就可以避免对RAM或虚拟内存乃至最坏情况下对外部存储器的访问。3. 用于cache的编译器开关除非是在进行内核开发、编译器开发或其他类型的底层系统编程,否则多数进行多核应用程序开发的人员不会关心手工管理cache。然而,在当前使用的多数主流编译器中,的确给出了编译器选项来提示可用的L1 cache或L2 cache的数量,或提示关于L1 cache或L2 cache的特
30、性。例如,Sun C+编译器具有xcache开关。该开关的参考指南显示了它的语法和用途。-xcache=c定义了优化器可以使用的cache属性。它并不保证使用任何特定cache属性。尽管这个选项可以单独使用,但它通常会是-xtarget选项的扩展部分,它的主要用途是用来覆盖-xtarget选项提供的一个值。-xcache=16/32/4:1024/32/1指定了如下内容:level 1 cache有:level 2 cache有:16KB32B通路大小4路相联1024KB32B通路大小直接映射开发真正利用CMP的软件要求对目标处理器或处理器系列的指令集以及内存使用进行详细的考虑。这包括了解优化
31、的机会,例如循环展开、高速向量处理、SIMD处理、MP编译器指示符和为某些值提供编译器提示,如L1 cache或L2 cache的大小。1.3.6 主存图1-2显示了寄存器、cache、ALU和主存之间的相对关系。除了外部存储器(例如硬盘、CD-ROM、DVD等)以外,RAM是开发人员在工作时面对的最慢的内存。同时RAM物理上位于处理器的外部,数据通过总线传送到处理器,使得其速度更慢。另一方面,RAM是对于多线程或多处理应用程序的软件开发人员而言最明显的部分。多数情况下处理器和任务间共享的数据保存在RAM中,每个处理器必须执行的指令在运行时将保存在RAM中,必须在多个处理器间同步的临界区(cr
32、itical section)也主要保存在RAM中。如果有任务或处理器被锁住,通常是因为内存管理问题。几乎在任何情况下,处理器和任务或多个agent之间的通信,将通过在运行时驻留在RAM中的变量、消息队列、容器和互斥量等产生。在软件开发者的多核应用程序编程视图中,内存访问和管理是一个重要的元素。如同已经讨论过的图1-2中显示的其他逻辑部件那样,您有权使用影响应用程序如何处理内存的编译器开关。您所选择的内存模型非常重要。在C+中通过new( )操作符创建的对象会位于空闲存储区(堆)或虚拟内存(如果数据对象足够大)中。空闲存储区逻辑上位于RAM中,而虚拟内存是外部存储器的映射。注意:我们将在第5章
33、中详细讨论进程或线程如何使用RAM。1.4 总线连接通常,计算机中的子系统通过总线进行通信。总线是子系统之间的共享通信连接Hennessy,Patterson,1996。总线是计算机中的部件之间的通道或通路。传统上,总线分为CPU-内存总线或I/O总线。基本的系统配置由两条主要的总线构成,即系统总线(也被称为前端总线,FSB)和I/O总线。如果系统有cache,通常还会有后端总线(Back Side Bus,BSB),用于连接处理器和cache。图1-6显示了一个简化的处理器-总线的配置。图1-6在图1-6中,FSB用于CPU和内存之间的数据传输。FSB是一条CPU-内存总线。I/O总线通常用
34、于向其他外设发送信息。注意在图1-6中,BSB用于在CPU、cache和主存之间移动数据。外围设备互连(Peripheral Component Interconnect,PCI)是I/O总线的例子。PCI提供了到它所连接的设备的直接连接。然而,PCI通常通过某种类型的桥接技术连接到FSB。由于总线提供了CPU、内存控制器、I/O控制器、cache和外设之间的通信通路,因此存在潜在的吞吐量瓶颈(throughput bottleneck)。多处理器配置会给FSB增加压力。目前的趋势是在一个芯片上增加更多的处理器,这会对基于总线的架构提出更高的通信要求。系统的性能受到CPU、内存和其他系统外设之
35、间所使用的总线的最大吞吐量的制约。如果总线的速度慢于CPU或内存,或者总线没有适当的容量、时序或同步,则总线会成为瓶颈,阻碍总体系统性能。1.5 从单核到多核在单核结构中,尽管很多当前的单核结构中包含特殊的图形处理部件、多媒体处理部件以及一些特殊的算术协同处理器,但您只需要关注一个(通用)处理器。但是即使使用单核或单处理器计算机,多线程、并行编程、软件流水以及多道程序设计也都是可能的。所以本节将澄清一些基本事实,帮助您从单核编程迁移到多核编程。1.5.1 多道程序设计和多处理多道程序设计(multiprogramming)通常是在讨论操作系统时被提及,而不是在讨论应用程序时被提及。多道程序设计
36、是一种调度技术,使得在任何时候都允许多个任务处于执行状态。在多道程序设计系统中,任务(或进程)共享系统资源,如主系统内存和处理器。在单核系统中,进程同时执行的假象是由于操作系统使用了时间片(time slice)技术。在时间片模式中,给每个进程一个小的时间间隔来执行。这些时间间隔被称作时间片,这些时间片非常短,而且操作系统能够非常快地切换上下文,这样就给出了在任意时刻执行多个进程或任务的假象。因此在单核架构并发执行两个主要任务(如刻录DVD的同时渲染计算机图像)的场景中,将系统称作多道程序设计。多道程序设计是一种调度技术。相反,多处理器是有着多个处理器的计算机。在这种情况下,是特指有着两个或多
37、个通用处理器。从技术上而言,有着CPU和GPU的计算机也是多处理器。但是为了本讨论的目的,我们集中于多通用处理器。这样,多处理是一种使用多个处理器来并发执行任务的编程技术。在本书中,我们主要关心属于并行编程范畴的技术。1.5.2 并行编程并行编程是使用并发执行的指令或任务来实现算法、计算机程序或计算机应用的科学技术。图1-7说明了每种类型的组成以及哪些是并行执行的。图1-7图1-7中的并行算法可以并行执行一组指令。instruction 1和instruction 2可以并发执行。instruction 5和instruction 6可以并发执行。在算法中,并行性发生在两条指令间。这和图1-7
38、中的并行计算机程序不同,在那里,工作单元是过程、函数或线程。过程A和过程B可以同时执行。除了过程A和过程B之间的并发外,它们各自内部也可能存在并发。过程A的函数可能并行执行。因此对于包含并行性的计算机程序,工作单元要大于算法中的工作单元。图1-7中的使用并行部件的计算机应用程序中具有最大的工作单元。任务A和任务B可能由很多过程、函数、对象等组成。当在应用程序级来查看并行编程时,所谈论的是更大的工作单元。除了任务,应用程序可能包含子系统,如后台网络组件或多媒体组件,这些组件相对于用户可执行的任务而言是同时在后台运行的。这里的关键点是图1-7中的每种结构都使用了并行编程,区别在于工作单元的大小,有
39、时候被称作粒度。注意:我们将在第4章进一步讨论并行性的级别。1.5.3 多核应用程序的设计与实现多核应用程序的设计与实现使用并行编程技术来设计可以利用CMP的软件。设计过程将一些任务的工作指定为两个或多个线程、两个或多个进程,或线程与进程的组合。然后,该设计可以使用模板库、类库、线程库、操作系统调用或低级编程技术(例如软件流水、向量化等)来实现。本书将介绍多线程、多处理、进程间通信、线程间通信、同步、线程库、多线程类库和模板库的基础知识。低成本的CMP实现使得一般的开发人员也可以进行并行编程和多线程编程。本书主要介绍使用可以跨操作系统环境移植的多处理和多线程技术来开发多核应用。我们将仅使用符合
40、操作系统POSIX标准的库以及符合ISO标准的C+特性。1.6 小结本章涵盖了考虑开发多核应用所需要理解的关键概念。本章介绍的重要内容为: 多核芯片是有着两个或多个处理器的芯片。这种处理器配置称为CMP。CMP当前范围是从双核到八核。 混合型多核处理器可以包含不同类型的处理器。Cell broadband engine是混合型多核处理器的实例。 根据开发者是系统程序员、内核程序员、库开发人员、服务器开发人员或应用程序开发人员,多核开发可以自底向上或自顶向下地实现。每组开发人员都会面对类似的问题,但是会从不同的角度来观察内核。 所有计划编写利用多处理器配置的软件的开发人员都应当熟悉目标平台的处理
41、器架构。到多核处理器特定特性的主要接口为C/C+编译器。为了更好地利用目标处理器或目标处理器系列,开发者应当熟悉编译器、编译器的汇编器子部件和连接器的选项。二级接口包括操作系统调用、操作系统同步与通信组件。 并行编程是使用被设计为并发执行的指令或任务集来实现算法、计算机程序或计算机应用的科学技术。多核应用程序开发和设计是关于使用并行编程技术和工具来开发可以利用CMP架构的软件。既然您已经了解了关于多核编程的基本思想和问题,第2章将介绍来自计算机工业领先位置的芯片生产商的4种多核设计,这些生产商为AMD、Intel、IBM和Sun。我们将了解Dual Core Opteron、Core 2 Duo、Cell Broadband Engine架构和UltraSparc T1多处理器内核是如何实现CMP的。