3.1 PC 架构

首先,我们看看当下许多PC中都使用的酷睿2(Core2)处理器的典型架构,然后分析一下它是如何影响我们使用GPU 加速器的(如图 3-1所示)。

3 CUDA硬件概述-LMLPHP

图3-1典型的酷睿2(Core2)系列处理器的结构图

由于所有的 GPU 设备都是通过 PCI-E(Peripheral Communications Interconnect Express)总线与处理器相连,所以我们以PCI-E2.0总线标准来讨论本章内容。PCI-E2.0是目前最快的总线标准,它的传输速率为5GB/s。在撰写本书的过程中,PCI-E3.0已经问世了,它的带宽明显提高了。

然而,为了从处理器中获取数据,我们需要通过与低速前端总线(Front-Side Bus,FSB)连接的北桥(Northbridge)。理论上,FSB的时钟频率最高只能达到1600MHz,而很多实际设计的产品就更低了。这通常只是一个高速处理器时钟频率的1/3.

访问内存也需要经过北桥,访问外设则需要经过北桥和南桥(Southbridge)。北桥服务于所有的高速设备,如内存、CPU、PCI-E总线接口等;而“南桥”则服务于低速设备,如硬盘USB、键盘、网络接口,等等。当然,把硬盘控制器直接连接到PCI-E总线接口上也是可能的。实际上,在这样的系统中,这是要获得高速RAID数据访问的唯一正确方式。

PCI-E是一个很有意思的总线。与其上一代PCI(Peripheral Component Interconnect,外围设备互连)总线不同,PCI-E提供一个确定的带宽。在原先的PCI系统中,每一个设备都可以使用总线的全部带宽,但一次只能让一个设备使用。因此,你增加的PCI卡越多,每个卡能够获得的可用带宽就越少。PCI-E总线通过引入PCI-E通道(lane)解决了这个问题。这些通道是一些高速的串行链路,这些链路组合在一起构成了X1、X2、X4、X8或X16 链路。目前,绝大多数GPU使用的至少是如图3-1所示的PCI-E2.0的X16规范,此配置下提供5GB/s的全双工总线。这意味着,数据的传入与传出可以同时进行并享有同样的速度也就是说,我们在以5GB/s的速度向GPU卡传送数据的同时,还能够以5GB/s的速度从GPU卡接收数据。但是,这并不意味着如果不接收数据,我们就可以10GB/s的速度向GPU卡传送数据(即带宽是不可以累加的)。

在一个典型的超级计算机或者一个台式机应用程序中,我们常常需要处理一个很大的数据集。一个超级计算机需要处理上千万亿字节(PB)的数据,而一个面计算机也要处理数十亿字节(GB)的高分辨率视频图像。这两种情况都需要从外设取来大量的数据,单块100MB/s的硬盘每分钟只能上传6GB的数据。按照这个速度,读取一个标准的1万亿字节(TB)硬盘上的全部内容需要两个半小时以上的时间。

如果使用集群系统中常用的MPI(MessagePassingInterface)作为通信软件,像图 3-1这样将以太网(Ethernet)接口连接到南桥芯片而不是PCI-E总线,构成的通信延迟是很大的。因此,诸如InfniBand这样的专用高速互连设备或者10千兆位(Gigabit)以太网卡常常连接到PCI-E总线上。不过,这就占用了原本可用于GPU的总线插槽。之前,并没有直接用于GPU的MPI接口函数。这类系统的所有通信都需要经过PCI-E总线连通到CPU,然后再原路返回。CUDA4.0SDK提供的GPU直连(GPU-Direct)技术就解决了这个问题。借助 SDK的支持,InfniBand卡就可以直接与GPU通信,而无须先经过CPU转发。SDK中的这项升级还支持GPU与GPU的直接通信。

Nehalem架构中有很多新的变化,其中最主要的变化就是用X58芯片组代替了“北桥”和“南桥”芯片。Nehalem架构引人了快速通道互联(Quick Path Interconnect,QPI)技术,该技术明显优于“前端总线”(Front Side Bus,FSB),达到了与 AMD 公司的超传输(HyperTransport)相当的水平。QPI是一种高速的、可用于与其他设备或CPU 直接通信的互连结构。在一个标准的Nehalem系统中,OPI的作用是连接内存子系统,并通过X58芯片组连接PCI-E子系统(如图3-2所示)。与Extreme/Xeon型号的处理器配合时,QPI的工作速率要么是 4.8GT/s',要么是 6.4GT/s。

3 CUDA硬件概述-LMLPHP

图3-2 Nehalem/X58系统

当使用X58芯片组和LGA1366处理器插槽时,共计有36个PCI-E通道。这就意味着,配置为X16时最多可以支持2个GPU卡,配置为X8时最多可以支持4个GPU卡。在LGA2011插槽出现之前,这是为GPU卡数据传输提供的最好的带宽解决方案。

在较小的P55 芯片组中,也可以使用X58方案。不过,这时仅有16个PCI-E通道。这就意味着,配置为X16时仅支持1个GPU卡,配置为X8时最多可以支持2个GPU卡。

从I7/X58芯片组开始,英特尔公司引入了如图3-3所示的沙桥(SandyBridge)设计方案。其最引人注目的改进之一是支持传输速率可达600MB/s的SATA-3标准。通过与固态硬盘(SSD)结合,在存/取数据时,“沙桥”可以提供很高的输入/输出性能。

沙桥的另外一个主要进步是引人了AVX(Advanced VectorExtensions,高级向量扩展)指令集,该指令集也同时被AMD的处理器支持。AVX允许向量指令最多可以并行处理4个双精度浮点数(256位或32字节)。这是一个很有趣的改进,可以使CPU上的计算密集型应用程序获得一个很高的加速比。

3 CUDA硬件概述-LMLPHP

图3-3 沙桥设计图

    然而,需要注意的是,LGA1155插槽的沙桥设计方案存在一个很大的问题,就是仅支持16个PCI-E通道,这将PCI-E的理论带宽限制在16GB/s以内,而实际带宽为10GB/S。在桌面处理器上,英特尔公司摒弃了向CPU中集成更多PCI-E通道的路线。仅仅是面向服务器的LGA 2011“沙桥 -E”插槽,才拥有数量可观的PCI-E通道(40个)。

相比英特尔公司的技术,AMD的设计方案又是怎样的呢?与英特尔公司不断地减少PCI-E通道的数量(除服务器系列产品外)不同,AMD始终保持一个固定不变的数量。AMD的FX芯片组,要么支持2个X16设备,要么支持4个X8PCI-E设备。AMD3+插槽与990FX芯片组一起提供了强劲的工作动力,即6GB/s的SATA端口以及最多可达4个的X16PCI-E插槽(通常以X8的速度运行)。

英特尔与 AMD的主要差别之一是,同一价位对应的处理核数是不同的。如果你考虑的仅仅是实际处理器核而不是逻辑核(如超线程),那么对于同一价位,AMD的处理器中通常会有较多的核。然而,英特尔处理器核的性能要高一些。因此,选择哪一种处理器主要取决你需要支持的GPU的数量以及分配给处理器核的工作负载水平。

在英特尔的设计方案中,你会发现,除了连接主存的带宽有差别外,系统周围的带宽都是基本相同的。在高端系统中,英特尔使用3个或者4个通道的内存;仅在低端系统中,英特尔才使用双通道的内存。而 AMD只使用双通道的内存,这就导致CPU与内存之间的可用带宽明显减少(如图 3-4所示)。

3 CUDA硬件概述-LMLPHP

图3-4 AMD结构图

相比英特尔的产品,AMD芯片组的一个重要优点是支持最高可达6个的6GB/S的SATASeria1 ATA)端口。如果考虑到系统中最慢的部件通常会限制整个系统的吞吐率,你就需要在这方面好好考虑再做选择。如果系统使用了好几个固态硬盘,SATA3将很快使“南桥”带宽超载。使用PCI-E总线也许是一个更好的选择,但是成本将会显著提高。

3.2 GPU 硬件结构

GPU的硬件结构与CPU的硬件结构有着根本的不同,图3-5显示了一个位于PCI-E总线另一侧的多 GPU 系统。

从图中可以看出,GPU的硬件由以下几个关键模块组成:

·内存(全局的、常量的、共享的)

·流处理器簇

·流处理器

3 CUDA硬件概述-LMLPHP

图3-5 GPU(G80/GT200)卡的组成模块图

这里最值得注意的是,GPU实际上是一个SM的阵列,每个SM包含N个核(G80和GT200中有8个核,费米架构中有32~48个核,开普勒架构中至少再增加8个核,如图3-6所示)。一个GPU设备中包含一个或多个SM,这是处理器具有可扩展性的关键因素。如果向设备中增加更多的SM,GPU就可以在同一时刻处理更多的任务,或者对于同一任务,如果有足够的并行性的话,GPU可以更快地完成它。

像CPU一样,如果程序员编写的代码将处理器使用核的数量限制为N个,比如2个那么即便是CPU厂商制造出4核的设备,用户也不会从中受益。因此,当计算机从双核CPU过渡到4核CPU时,很多软件都必须重写以利用新增加的核。通过不断地增加SM的数量以及每个SM中的核数,英伟达硬件的性能持续地提高。设计软件时,应该意识到下一代处理器中SM的数量或者每个SM中的核数可能翻一番。

现在让我们更深入地看看SM。每个SM 都是由不同数量的一些关键部件组成,为了简单起见,没有在图中画出。最重要的部分是每个SM中有若干个SP,图中显示的是8个SP,在费米架构中增加至32~48个,在开普勒架构中增加到192个。毋庸置疑,下一代产品中每个SM中SP的数量极有可能继续增加。

每个 SM 都需要访问一个所谓的寄存器文件(register File),这是一组能够以与 SP 相同速度工作的存储单元,所以访问这组存储单元几乎不需要任何等待时间。不同型号GPU中寄存器文件的大小可能是不同的。它用来存储SP上运行的线程内部活跃的寄存器。另外,还有一个只供每个 SM 内部访问的共享内存(shared memory),这可以用作“程序可控的”高速缓存。与CPU内部的高速缓存不同,它没有自动完成数据替换的硬件逻辑--它完全是由程序员控制的。

对于纹理内存(texture memory)、常量内存(constant memory)和全局内存(global memory), 每一个SM都分别设置有独立访问它们的总线。其中,纹理内存是针对全局内存的一个特殊视图,用来存储插值(interpolation)计算所需的数据,例如,显示 2D 或 3D 图像时需要的查找表。它拥有基于硬件进行插值的特性。常量内存用于存储那些只读的数据,所有的GPU卡均对其进行缓存。与纹理内存一样,常量内存也是全局内存建立的一个视图。

图形卡通过GDDR(Graphic DoubleData Rate)接口访问全局内存。GDDR是DDR(Double Data Rate)内存的一个高速版本,其内存总线宽度最大可达512位,提供的带宽是CPU对应带宽的5~10倍,在费米架构GPU中最高可达190GB/s。

每个SM还有两个甚至更多的专用单元 (Special-Purpose Unit,SPU),SPU专门执行诸如高速的24位正弦函数/余弦函数/指数函数操作等类似的特殊硬件指令。在GT200和费米架构GPU上还设置有双精度浮点运算单元。

3 CUDA硬件概述-LMLPHP

图3-6 SM内部组成结构图

3.3 CPU 与GPU

    现在你已经对GPU的硬件结构有了初步的了解,你也许会认为它很有意思。但对于程序设计,这意味着什么呢?

参加过大型项目开发的人都知道,项目开发分成不同的阶段,每个阶段的任务由不同的工作组来完成。可能有一个软件规格指定组,一个设计组、一个编码组和一个测试组。让团队中每个人完全了解开发链中在他上游和下游的工作,这对高质量地完成项目开发是很有益处的。

以测试为例,如果设计人员不考虑测试,那么他就不会在程序中设置用于检测因具体软件而引发的硬件故障的测试手段。如果只有发生了硬件失效,测试组才能测试出此硬件故障,那么只能修改硬件让它失效。无疑这是很难做到的。相反,编程人员设计一个反映硬件错误标志的软件标志就容易得多,这样硬件故障就很容易检测出来。如果在测试组里工作你就会看到如果不这么做,测试工作有多难。除非你狭隘地看待你的岗位职责,你可能才会说测试不关我的事。

最优秀的工程师都是那些关注在他工作流程之前和之后工作的人。作为软件工程师,知道硬件的工作原理总是有益的。对于串行代码的执行,人们可能会关注到它是怎么工作的,但这并没有达到非如此不可的地步。大多数开发人员可能从来没有学习过计算机体系结构的课程或者读过这方面的书籍,这是很令人惭愧的。这就是我们曾经看到有如此多的低效率软件的主要原因之一。以我自己的经历为例,我在11岁时开始学习BASIC语言,在14岁时就使用 Z80 汇编语言,但只有进人大学后才真正开始理解计算机体系结构。嵌人式领域的工作经历会培养你的硬件方面的动手能力。由于没有Windows操作系统帮助你管理处理器,因此程序设计是一件很底层的工作。嵌入式项目中,上市的产品通常数以百万。糟糕的代码(sloppycode)意味着对CPU和现有内存的低效使用,它反过来需要更快的CPU或更多的内存。对于一百万件产品,每件附加50美分的费用,就是增加了50万美元的成本。这也会带来增加的设计与编程时间。显而易见,写更好的代码比买更多的硬件要划算得多。

时至今日,并行程序设计还是与硬件紧密相连的。如果你只埋头编程而不关心程序的性能,那么并行程序设计并不难。但是如果想充分发挥硬件的性能,你就需要知道硬件是如何工作的。举个生活中的例子,大多数人都能够在一档的情况下安全、缓慢地驾驶汽车,但是如果不知道还有其他档,或者不具备使用它们的知识,你就永远不能快速地从A点到达B点。学习硬件类似于学习汽车驾驶时使用手动换档--刚开始有点复杂,但熟能生巧,一段时间后就会变得自然。用相同的比喻,你也可以买一辆带自动档的汽车,就像使用一个由悉底层硬件工作机理的程序员开发的函数库。但是,在不了解硬件工作原理的情况下开发软件,其结果往往不是最优的实现。

3.4 GPU计算能力

CUDA支持多个级别的计算。最早的G80系列图形卡就是在配有CUDA的第一个版本的情况下上市的。硬件的计算能力是固定的。为了升级到一个新的版本,用户必须升级硬件。听起来虽然像是英伟达公司试图强迫用户购买更多的硬件,但是它确实给用户带来了好处。因为当提升一个计算级别时,你就从一个老的平台迁移到了一个新的平台,新的图形卡与原先的图形卡价格相同,计算能力却翻了一番。英伟达公司至少每隔几年就推出一个新的平台,在CUDA出现的短短数年内,人们可以获得的计算能力已经有了巨大的提高。

不同计算能力之间的差别列表,作为本书的一部分,可以在附录G中找到。因此,我们仅仅在这里介绍不同计算能力之间的主要差别。作为开发者,这是需要知晓的。

3.4.1 计算能力 1.0

计算能力1.0出现在早期的图形卡上,例如,最初的8800Ultras和许多8000系列卡以及TeslaC/D/S870s卡。计算能力1.0卡的性能缺陷主要与原子操作有关。原子操作是指那些必须一次性完成、不会被其他线程中断的操作。要实现这一点,硬件就要在原子函数的人口实现一个栅栏点(barrier point)并确保相应操作(例如,加、减、求最小值、求最大值、逻辑与、逻辑或、逻辑异或等)作为一个整体来完成。计算能力1.0现在已经退出市场了。因此,无论为了什么目的和意义,这个限制都可以忽略不计。

3.4.2 计算能力 1.1

计算能力1.1出现在许多9000系列图形卡后期推出的产品上,例如,曾经红极一时的9800GTX卡。相对于计算能力1.0的G80硬件,这些卡基于G92硬件。

计算能力1.1带来的最主要的变化是支持数据传送和内核程序的重叠执行。当然,这个变化出现在大多数,但不是所有的计算能力1.1卡上。SDK调用cudaGetDeviceProperties(函数返回 deviceOverlap属性,该属性定义了这项功能是否可用。实现这项功能需要一个很巧妙的重要改进--双缓冲(double buffering),其工作原理如图 3-7 所示。

3 CUDA硬件概述-LMLPHP

图3-7 单条 GPU的双缓冲区技术

要想实现这项功能,我们需要将通常使用的内存空间加倍。如果你的目标市场仅有512M字节显存的卡的话,这一点也许是一个问题。但是,如果使用的是面向科学计算的 Tesla卡,那么你拥有的GPU存储空间最高可达6GB,实现这项功能就没问题了。让我们看看它的操作步骤,如下所示。

时钟周期0:在GPU的存储空间中划分出两块缓冲区,CPU将一个数据包写人“缓冲区 0”中。    

时钟周期1:CPU调用GPU上的一个CUDA内核程序(即一个GPU任务),然后立即返回(这是一个非阻塞调用)。然后,CPU从硬盘、网络或者其他地方取来一个数据包。与此同时,GPU正在后台处理交给它的数据包。当数据包取来后,CPU开始将其往“缓冲区1中写。

时钟周期2:当CPU写完后,它又调用一个内核程序来处理“缓冲区1”。然后检查在时钟周期1调用的、处理“缓冲区0”的内核程序是否完成。如果还没有完成,CPU则一直等待直至它完成。完成后,CPU取走“缓冲区0”中的计算结果,然后把下一个数据包写人“缓冲区0”。在这个过程中,本时钟周期一开始就启动的内核程序,则一直在处理GPU上“缓冲区 1”中的数据。

时钟周期N:重复时钟周期2。在GPU处理一个缓冲区的同时,让CPU选择另外一个缓冲区进行读或写操作。

GPU-CPU和CPU-GPU的数据传送是在相对较慢的PCI-E总线(5GB/s)上进行的这个“双缓冲”技术显著地掩盖了通信延迟,使CPU 和GPU都处于忙碌状态。

3.4.3 计算能力 1.2

计算能力1.2设备是与低端的GT200系列硬件一起出现的。最早的产品是GTX260和GTX280卡。随着GT200系列硬件的出现,英伟达公司通过将卡上的多处理器数量增倍,使得单个卡上的 CUDA核(CUDA core)处理器的数量几乎增加了一倍。因此,与上一代产品G80/G92相比,这些卡的性能翻了一番。CUDA核与多处理器的内容将在后续章节中介绍。

在将多处理器数量增倍的同时,英伟达公司还将一个多处理器中并发执行的线程束的数量从 24 增加到了 32。“束”是在一个多处理器内执行的代码块。每个多处理器内可调度“束’的增加有利于我们提高性能,这一点将在后续章节中介绍。

在计算能力1.0和计算能力1.1中常见的对全局存储器的访问限制和共享存储器中存储片冲突(bank confict),在计算能力1.2中大大减少了。这使得GT200系列硬件更容易编程明显地提高了很多以前艰难编写的CUDA 程序的性能。

3.4.4 计算能力 1.3

计算能力1.3设备是在GT200升级到GT200a/b修订版时提出的,这次升级发生在GT200系列发布不久。从那时开始,几乎所有的高端卡都兼容计算能力1.3。

计算能力1.3带来的最主要的变化是支持有限的双精度浮点运算。由于GPU是针对图形处理的,所以对快速的单精度浮点运算要求很高,但是对双精度浮点运算要求有限。双精度浮点运算性能通常要比单精度浮点运算性能低一个数量级,所以如果程序中只有单精度浮点运算,才能发挥硬件的最大功效。但是在很多情况下,单精度浮点运算和双精度浮点运算会同时出现在程序中,因此硬件中同时设置专用的单精度浮点运算单元和双精度浮点运算单元是最理想的。

3.4.5 计算能力 2.0

计算能力 2.0设备是伴随费米架构硬件出现的。调整应用程序以适应费米架构的最初指导可参见英伟达公司的网站 http://developer.nvidia.com/cuda/nvidia-gpu-computing-documentation。计算能力2.x硬件的主要改进如下:

  • 在每个SP上引入了16K~48K的一级(L1)缓存。
  • 在每个SM 上引人了一个共享的二级(L2)缓存。
  • 在基于Tesla的设备上支持基于纠错码(Error Correcting Code,ECC)的内存检查和纠错。
  • 在基于 Tesla的设备上支持双复制(dual-copy)引擎。
  • 将每个SM 的共享内存容量从16K扩展到48K。
  • 为了优化数据的合并,数据必须以128字节对齐共享内存的片数从 16增加到 32。

下面让我们选择几个重要的改进,详细分析一下它们的实现。首先,我们分析一下一级缓存以及引人它意味着什么。一级缓存是设置在芯片内的,它是最快的可用存储器。除了纹理和常量缓存外,计算能力1.x的硬件中并没有缓存。引人缓存,使程序员更容易编写出适合在GPU硬件上工作的程序,还允许应用程序不必遵循在编译时已知的存储器访问模式。但是,为了利用好缓存,应用程序要么需要具有一个顺序的存储器访问模式,要么需要对某些数据反复使用。

费米型硬件上的二级缓存容量最高可达768K。重要的是,它是一个统一的缓存。这意味着它是一个共享的缓存,对所有的SM 提供一个一致的视图。通过二级缓存来实现程序块间通信,要比通过全局原子操作实现快得多。访问GPU上的全局存储器,需要越过线程块比较起来,使用共享缓存要快一个数量级。

对于数据中心(data center)而言,支持ECC存储是必须的,因为ECC存储器具有自动的检错和纠错功能。电子设备会产生少量的电磁辐射。当与其他设备靠得很近时,这个辐射会改变其他设备中存储单元的内容。虽然这种情况发生的概率很小,但是由于数据中心的设备摆放密度不断增加,出错的概率将会增大到无法接受的水平。因此,就需要引人ECC来检测和纠正在一个大型数据中心中可能出现的“单个二进制位反转错误”。当然,引人ECC技术会减少可用的 RAM 容量并降低访存带宽。这对图形卡而言是一个严重的缺点,所以目前仅有Tesla卡采用了ECC 技术。

“双复制”引擎是将前面介绍过的“双缓冲技术”扩展应用到多“流”处理技术,“流”的概念将在后续章节中详细介绍。简单地说,“流”就是N个独立的内核程序以流水线的方式并行执行,如图 3-8所示。

3 CUDA硬件概述-LMLPHP

图3-8 流的流水线处理技术

请注意图中内核程序段一个接一个执行的过程。每个复制操作被另一个流中执行的内核程序所隐藏。内核程序与复制引擎是并发执行的,因此相关器件的利用率达到最高。

需要说明的是,“双复制”引擎在绝大多数诸如GTX480或GTX580 这样的高端费米型GPU中是真实存在的。但是,只有Tesla卡中的双引擎对CUDA驱动程序是可见的,即可以由CUDA 驱动程序直接操纵。

共享存储器变化较大,它存在于混合的一级缓存中。一级缓存的容量为64KB。但是为了保证向后兼容性(backward compatibility),必须从中至少划分出16KB的存储空间给共享存储器。这就意味着,一级缓存的实际容量至多为48KB。实际工作中还可以通过一个转换开关,将共享存储区和一级缓存区的功能相互转换,即共享存储器的容量为48KB而一级缓存的容量为16KB。共享存储器的容量从16K提升为48K,某些特定的程序会从中获得巨大的好处。

由于新一代GPU引人了一级和二级缓存,为优化访存而提出的对齐(alignment)要求就更加严格了。两级缓存中,缓存存储块(cacheline)的大小均为128B。而每次访问缓存取来的最少数据量就是一个“存储块”。因此,如果你的程序是顺序访问数据元素,那么这个要求会发挥很好的作用。事实上,绝大多数CUDA程序都是这么工作的,即一组线程读取的都是相邻的存储单元。不过这个改进也带来了一个新的限制,就是数据集应该是128B对齐的。

但是,如果你的程序中每个线程的访存模式是稀疏而分散的,那么你就应该屏蔽掉这个“对齐”要求,并转回到 32位的缓存操作模式。

最后,我们再看看“共享存储器的片数从16增加到32”这个改进。新一代GPU会从中获得巨大的好处。它允许当前线程束(包含32个线程)中的每一个线程都可以向共享存储器中的某一片写人数据,而不会引起共享存储片冲突。

3.4.6 计算能力 2.1

计算能力 2.1出现在专门面向游戏市场的专用卡上,例如,GTX460和GTX560。这些设备在体系结构方面的改进如下:

  • 每个SM 中的CUDA 核心由原先的 32个增为48个。
  • 每个SM 中面向单精度浮点数的专用超越函数计算部件由4个增至8个。
  • 双束调度器代替单束调度器。

x60系列卡对中端的游戏市场一直有很强的渗透能力,所以如果你的应用程序面向这类消费市场,那么了解上述改进的内涵是很重要的。

计算能力2.1硬件中一个值得注意的变化就是牺牲掉双精度浮点数的运算器件来换取CUDA核数量的增加。对于单精度浮点数和整数运算占主要地位的内核程序而言,这是一个很好的取舍。绝大多数游戏主要进行单精度浮点数和整数的数学计算,几乎不处理双精度浮点数。

个线程束就是一组线程,在后续章节中我们将详细介绍。在计算能力2.0的硬件上,单東调度器需要两个时钟周期来从整个束中取出2条指令执行。在计算能力2.1的硬件上,双東调度器每两个时钟周期分发4条指令,而不是2条。在现在的SM硬件中,有3排、每排16个的 CUDA核,共计48个CUDA核心,而不是原先的2排、每排16个的CUDA核。如果英伟达公司还能再挤进16个一排的CUDA核,那就更理想了,也许在未来我们能看到这样的硬件。

计算能力2.1硬件的确采用了类似于从最早的奔腾CPU开始就一直采用的超标量(superscalar)技术。要想充分利用所有的核,硬件需要在每一个线程中识别出指令级并行性(Instruction-Level Parallelism,ILP)。这与原先推荐的通用的线程级并行性(Thread-LeveParallelism,TLP)有很大的不同。要想体现出IP,指令之间应该是相互无关的。借助专用的向量类库是实现ILP最早的方法之一,本书的后续章节将详细介绍。

计算能力 2.1硬件的性能是变化的。某些著名的应用,如FoldingatHome,使用计算能力2.1硬件的性能就非常好。其他诸如视频编码压缩这样的应用,由于很难从中挖掘出ILP而且存储器带宽是一个关键因素,所以实际使用性能就很糟糕。

截至撰写本书的时候,开普勒型GPU和新的计算能力3.0平台的最后细节,还没有公开地发布”。针对已经公布的开普勒型 GPU特性,本书在第12章中将进行深入的讨论。

03-21 00:57