【IT168 文档】CUDA和支持CUDA的设备正在共同发展,在新一代产品中提供了更多的性能和功能。NVIDIA最近引入的GeForce 200系列和Tesla 10系列产品,展示了这种发展的迅速,其硬件功能几乎是上一产品线同一价格水平可用功能的两倍,而且200系列还增加了一些有价值(而且不可或缺)的新功能。
原来G80中包含6.98亿个晶体管,而GTX280中包含14亿个晶体管,这清楚地表明了NVIDIA的下一代CUDA硬件是原来的两倍。我的经验表明,NVIDIA的确在200系列中很好地使用了这些晶体管。与上一代G80硬件相比,我的单精度代码不进行任何变化,在新硬件上的运行速度几乎是原来的2倍。
下列几项汇总了200系列架构的新特征和功能:
硬件现在支持双精度算术运算(GTX280中有30个64位浮点单元)。
全局存储器更大、更快、更易用。联合规则已经放松——这使得获得高全局存储器性能更加容易,而且全局存储器带宽高于100 GB/s,几乎是G80架构的两倍。
每个硬件线程的单精度寄存器数已经翻倍(但相对于上一架构,使用双精度时的可用寄存器数没有变化)。
200系列的共享存储器支持32位原子有符号和无符号整数函数,全局存储器支持64位函数。
200系列现在包括warp vote函数。
线程处理器数几乎已经翻倍,240对128,而且每个多处理器支持更多的活动warp和活动线程。
200系列的硬件功能得到了增强,可以同时执行MAD和MUL,这有助于一些应用程序更好地达到顶峰性能。
让我们仔细研究一下这对于CUDA的意义。
对于许多应用程序,最重要的新功能是硬件双精度算术运算。NVIDIA GPU的速度和大规模的并行性为大众带来了超级计算。处理超大型问题和数据集时,数字噪音可以快速积累(由于浮点不准确性),从而导致垃圾结果。例如,物理模拟可以突然展示惊人的非物理行为,而且以前有效的模拟可能变得不稳定,并开始生成无限值NaN或其他无意义的值。虽然并非对于所有计算问题都是必要的,但使用更高精度的浮点表示(比如64位双精度浮点数)确实很有帮助。[在以后的文章中,我们将介绍如何快速组合单精度与双精度计算来加速结果。]
200系列架构是第一个包括了硬件双精度的架构。正如对第一代产品所期望的一样,我们为性能改进保留了一些空间(因为多处理器中的线程处理器全部共享单个双精度硬件单元)。我的经验表明,只要仅在需要保留数字准确度时才使用双精度,性能只会有略微的降低。当然,问题因情况而异。
大多数程序员将会发现,使用10系列架构获得高性能要容易得多。
通过将寄存器数翻倍,NVIDIA允许CUDA程序员更容易地将充足的单精度数据加载到寄存器中,以减少(或尽可能减少)全局存储器存在的大多数瓶颈。因为双精度值需要的存储空间是单精度的两倍(8字节对4字节),所以200系列上的双精度寄存器数量与G80和G92架构上的单精度寄存器数量相同。
全局存储器的带宽也几乎翻倍。
10系列主板提供了高于100GB/s的全局存储器带宽。对于32位浮点数,相对于G80和G92架构,10系列中的全局存储器带宽已经落后了,因为线程处理器数几乎翻倍,如下表所示。
架构 / 卡 全局存储器带宽 (GB/s) 处理单元数 全局存储器每秒内每个处理单元可用的32位操作数(只考虑带宽,单位:百万)
G80 / 8800 Ultra 104 128 203
10系列/ GTX 280 141 240 146
由于每个多处理器(8个线程处理器)有一个双精度单元,将其翻倍将消耗两倍带宽来应对,因此,双精度(64位浮点数)性能复杂化了。200系列的CUDA开发人员可能发现,使用单精度浮点数时带宽受限的应用程序在切换到双精度时,可能变为计算受限。
此表演示了NVIDIA硬件设计团队确实做了一项了不起的工作,因为他们提供了一个新的产品,与上一代产品同一价格水平相比,它的全局存储器带宽和双精度功能几乎翻倍。
所有CUDA应用程序最大的一个成功原因是,在200系列放松了联合规则,全局存储器更易于以一种高性能的方式访问。“CUDA编程指南”的5.2.2小节详细介绍了用于执行存储器事务处理的协议。以下是三个值得注意的特征:
1. 为任何模式的地址请求实现了联合,包括对同一地址的多个请求。以前的架构需要按顺序访问字(word)。实际上,这意味着更多的CUDA应用程序将获得极好的全局存储器性能,而且CUDA程序员将不再需要发明(如果可能)应急方案来保证其全局存储器访问模式的正常运行。
2. 如果半warp地址字位于n个不同的分段中,则只执行n个存储器事务处理。例如,如果n=2,则与以前架构中发生的16个事务处理相比,将只执行两个存储器事务处理(即是原来事务处理的1/4)。
3. 不幸的是,存储器中的未使用的字仍要读取,所以,它们浪费了带宽,尽管硬件将执行尽可能最小的存储器事务处理。
200系列支持有符号和无符号整数的原子操作。atomicExch()是个例外,它只支持单精度浮点数。原子函数对驻留在全局或共享存储器中的32位或64位字执行读-改-写原子操作。例如,atomicAdd()读取全局或共享存储器中某个地址的32位字,加一个整数,然后将结果写回同一地址。操作是原子的,表示保证在不受其他线程的干扰下执行,即在操作完成之前,没有其他线程可以访问此地址。
warp vote函数可用于200系列。如果需要的话,这些函数提供在warp的所有线程中执行快速谓词操作(比如,检查条件是真还是假)时必不可少的功能:
int __all(int predicate);
为warp的所有线程求值指定谓词,当且仅当谓词对所有线程求值为非零时,才返回非零。
int __any(int predicate);
为warp的所有线程对指定的谓词求值,当且仅当谓词对所有线程求值为非零时,才返回非零。
最后,对硬件同时执行MAD和MUL操作能力的改进应该有助于一些应用程序实现更接近峰值性能的FLOP(浮点数操作)速率。
有关详细信息,请参阅CUDA Zone论坛。另外,还建议在NVIDIA网站上下载最新版本的“CUDA 编程指南”。当前版本是2.0b2,其中包括对新功能和API的介绍(http://developer.download.nvidia.com/compute/cuda/2.0-Beta2/docs/Programming_Guide_2.0beta2.pdf)。
这可能是升级到200系列支持CUDA设备的一个极佳时机。激烈的竞争(http://www.tgdaily.com/content/view/38243/135)导致了明显的降价措施,现在是进行交易的最佳时机!