首页 > DIY硬件 > 显卡 > 应用 > 正文

不仅是游戏 谈Fermi架构下通用计算的优化

2012-01-05 00:06 出处:pconline 作者: DIY整理 责任编辑: liangjiewen

前言:

  朋友们可能常常听到CUDA:苦大,不过它而且测试也嚷嚷的,结果深究它是神马?相信没多少人有了解。下面我来为你们介绍。

  CUDA是NVIDIAGPU通用运算技术,它运算速度高效精炼而著称。而X86则在通用领域有着天然的优势,即具备最广泛的软件应用支持。相信,至今没有一个指令级体系可以拥有如此广泛的软资源。CUDA要做到如此兼容,并非简单CUDA-x86编译器可以解决。

  不过广泛的支持是要付出一定的代价。因此每一代新的x86处理器设计时都需要兼容前一代处理器的指令。所以导致x86臃肿的架构。同时,你可以发现,同样的应用可以不加修改地在新x86处理器上得道更高效的运行。

谈Fermi架构下通用计算的优化
四块Tesla组成

  相对于通用架构的CUDA体系,在代码编写方面是一种更加接近硬件的语言,因此如果要在新CUDA硬件上更加高效实现以往应用,则需要在指令应用到新的技术。在x86硬件方面,在此10年几乎没有革命性的变化,相对而言G80自从发布以来,CUDA硬件拥有了多次不为用户所知的重要变化。

  首次是最原始的G80架构,代表的产品是8800GTX。紧跟的是GT200核心的变革,最后也是最新的CUDA硬件Fermi的到来。

谈Fermi架构下通用计算的优化

流处理器越多实时线程越多

  CUDA硬件区别一般的多核处理器,其最大不同是拥有更多的运算单元。举例说,一般的4核处理器只拥有4个物理处理器核心。而一款GTX480却拥有480个流处理器,而GTX580更具备512个CUDA核心之多。

  因此,高效的应用需要程序中建立足够多的线程让GPU充分地工作。当然,一般较为简单的做法是为不同的核心创建不同的代码,让其执行的时候去识别不同设备ID来调用不同的内核代码。

  当然,更为高效的做法是编写一个具备自适应核心数量的代码。此方法不但可以具备良好的兼容性,同时更可以不加修改地适用于往后的新硬件。

  在流处理器架构上,每一代产品都有不同的变化。首次采用此命名是因为该单元具备通用执行的能力。即该单元可以同时执行整型和浮点指令。在G80芯片上,SPs单元具备全速的单精度浮点运算以及24位整型指令。而在Fermi的CUDA核心里面,便可以同时执行全速的单精度以及32位整型运算。

谈Fermi架构下通用计算的优化
Block中的线程映射

  注释:在CUDA中所说的shared memory并非直接的翻译为共享内存,它是由于高速晶体管组成的高速内存,速度和寄存器高速缓存一致,并且对程序员不透明。而且shared memory和代码中的指令同名,因此一般不作翻译。

新存储体系的应用优化

  存储体系是变化是GPU向CPU靠拢的一个标志,第一代的G80的存储体系和GT200体系都是寄存器、shared memory和DRAM(显存)架构。因此,一般高级应用需要到高速缓存来提速的时候,通常需要shared memory代替或者用只读的纹理缓存代替。由于硬件的限制,此前两代对于一些通用算法实现的效率受制在高速缓存上。

谈Fermi架构下通用计算的优化

  NVIDIA通用技术的软件层次,可以看到通过cuda的支撑,显卡可以实现C,C++,java,fortran等高级语言的编程。另外可以在游戏通过OpenCL,DC等实现游戏的物理特特效和高级AI。

  最新的Fermi体系在前两代基础上,新增加了读写统一的高速一、二级缓存。新的存储体系的变化可以减少每个线程读写DRAM的机会,因为每次通过I/O操作DRAM会导致数百个频率周期的损失。而当每个SM寄存器不足的时候,shared memory以及SM上的一级缓存来代替DRAM。寄存器、shared meory以及一级缓存几乎没延时周期。

谈Fermi架构下通用计算的优化
在蛋白质折叠运算中 会使用到大量的高速缓存来提速

  即使一级缓存溢出,在Fermi上还有二级缓存做缓冲。此读写统一的高速二级缓存彻底替换了前两代核心的只读纹理二级缓存。不过,先要说明是基于Fermi的GTX480/GTX58二级缓存限制在768KB大小。当然,这对于CPU上数MB以及上10MB的缓存来说还是十分稀少。不过不要忘记显卡上具备的惊人的显存带宽,轻松上100GB/s的带宽并非CPU可以相比。

谈Fermi架构下通用计算的优化

  如图所示,解决块冲突就是让线程互不干扰地执行,解决了款冲突便可以瞬间把带宽提升到数百GB/s。

  在显存带宽的使用上,需要并行使用才能达到最大的理论带宽。当操作GPU DRAM的时候如果读写相关便会导致带宽的巨幅下降。在一些显存控制器较多的高端芯片上,还要考虑到区域冲突。

  如果核心只有一个32bit显存控制器实现I/O操作,就不用考虑算法对显存的冲突。不过,要是在GF110核心上,它核心拥有512bit带宽,因此一共拥有16个显存控制器,为此要在算法中均衡地使用所有显存控制器,避免某些操作集中在个别显存控制器上造成带宽下降。

Fermi中加强的双精度浮点/整型单元

  CUDA应用中,双精度缺乏有效的支持是它劣势。不过Fermi架构中,GF100/GF110大大加强了双精度浮点单元以及32位全速整型单元的数量。可以知道,即使GPU具备数量庞大的单精度浮点,但在庞大的矩阵迭代运算当中,小小的误差将在N次迭代造成结果病态的变化。(双精度能力在GeForce产品上并没达到,只在Tesla上实现)。

  Fermi芯片的双精度浮点能力是单精度的二分之一,是GT200的八倍。而整型运算能力更和峰值单精度性能一样。整型单元同样重要,譬如在前代架构中,只能实现全速的24位整型运算,其原理是借助单精度单元的尾数运算器来实现。而Fermi中的每个核心都拥有一个32位整型单元实现,效能有极大的提高。

谈Fermi架构下通用计算的优化

  Fermi的CUDA核心的当中增加了一个全速的整型单元,因此可以实现单周期的32bit整型运算。在双精度运算方面,只有Fermi Tesla具备加强64位运算,而Fermi Geforce的双精度能力依然是单精度峰值的八分之一。

一级缓存shared memory变换

  在前两代架构当中,GPU核心的每组SM都具备16KB shared memory为程序员用代码调度。而在Fermi核心当中,每组SM配备了一块64KB可配置的高速存储器,其速度接近寄存器和高速缓存的速度。

  此64KB可以分配为16KB shared memory以及48KB高速缓存,或反之。因此在使用Fermi架构的时候,每组SM可以具备更多的激活线程,并还拥有一级缓存作为寄存器益处的数据缓冲,从而可以达到更好的速度。

谈Fermi架构下通用计算的优化
细菌核糖体离子置换的GPU加速

  SM中最大可以分配48KB的一级缓存,因此当访问不规则数据时L1起到很好的作用。而前代架构的代码一般是依靠纹理数据的绑定来实现不规则数据的操作,并且此操作只能读取而不能写入。
 
总结:

谈Fermi架构下通用计算的优化

  GPU通用在physX上的应用时,由于Fermi支持多个内核函数并行运行,因此当物理模拟的时候,允许多个轻量级的内核函数来协助实现。

  Fermi每个SM可以拥有更多的CUDA核心,同时寄存器也相应地增加,因此设计程序时必须增加每个block里面的合作线程来提高效率。更大的shared memory可以加大线程的公共数据域,减少DRAM的通信代价。当出现巨大数据排序的时候,可以透明地应用到GPU的二级缓存。总体来说,Fermi对应用最大影响是存储结构的变化,在后面的CUDA硬件也将在加强运算单元外继续提升它的存储体系效能。

  要发挥Fermi体系的性能,除了让CUDA核心满负载,还要利用到Fermi改进的存储体系。譬如在随机操作上,Fermi的L2起到极大的提速作用。在优化方面,当存储系统优化达到极限时,便可以考虑指令级的优化。此可以根据CUDA核心的硬件单元来进行改良,以便达到指令效能的最大化。好了,科普到这儿,有问题的童鞋举手。

什么是超极本 - 为纤薄探索一种全新的定义,轻便又同时强大,这就是超极本。由英特尔科技所推动,产业生态伙伴共同支持的超极本,作为一种全新的移动计算设备,为用户提供全面综合的最佳体验。