POPPUR爱换

 找回密码
 注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

搜索
查看: 2556|回复: 6
打印 上一主题 下一主题

程序猿玩家细说GTX 680轻取百万线程代码

[复制链接]
跳转到指定楼层
1#
发表于 2012-8-9 18:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
说起通用计算、并行计算、加速计算,NVIDIA CUDA无疑是很多开发人员的首选。虽然还有开放的OpenCL,但在开发环境方面还不够,CUDA则在经过大力推广后拥有了不错的群众基础。GeForce GTX 600时代虽然这方面的宣传似乎少了很多,开普勒架构的浮点性能看起来也不强,但其实在并行计算方面仍然有很多进步的,其中蕴藏着不少能量,比如费米架构首创性地加入了和处理器一样的统一读写二级缓存,GK104核心更把底层的SMX进行了变革。
今天就有一位技术宅程序猿同学,利用一块GeForce GTX 680 4GB,展示了如何在开普勒上取得百万级别的线程代码。看不懂不要紧,内行看门道,外行看热闹。
据说,技术宅的厕纸用完了之后就会用书本。
技术宅受到刺激后,迷上了超大规模程序设计,那个叫什么CUDA神秘兮兮的东西。
平台艳照。
CUDA的环境配置:首先安装CUDA工具箱,然后安装显卡驱动,最后安装CUDA SDK。前两步必不可少,第三步可以省略。
G80、GT200的SM架构差异,导致了CUDA程序上的不同优化。

老架构就不花时间去讨论了,直奔在通用计算大放异彩的费米架构,革命性的统一读写一级、二级缓存有些模仿CPU设计的味道。下面结合硬件来说说CUDA如何根据它来优化。
费米的SM拥有3万个高速寄存器,保证了线程的快速切换,要知道八核心CPU也不过几百个而已。16路高速存储通道来并行操作64KB的片上高速缓存,速度可达到1TB/s级别。
开普勒再度加强,在晶体管数量控制在35.4亿个的情况下竟然塞进了比费米多一倍的CUDA核心,寄存器也翻番达到6.5万个,存储通道也多了一倍。
要让CUDA程序为开普勒架构优化,首要任务是让Block里面的线程尽量的多。GT200 SM允许的活动线程是1024个,费米优化的代码可以增加到1536个,开普勒则进一步提高到2048个(注:GK110核心也会如此)。
这个是软件层次对应的硬件层次。Block编程上的线程块在SM里分时运行,一个CUDA程序会有多个blcok并行运行,而每个block线程块又包含了数十到上百的线程,也就构成了CUDA。
不同架构对应不同的计算规格,代码优化也要针对性地进行,比如开普勒可以支持更大的block内部线程,可以让更多线程进行片上同步工作,另外费米和开普勒有DRAM缓存,所以对DRAM优化的力度没有G80那么吃力。
开普勒在CUDA上加入了更大的革新,特别是支持多内核函数的并行执行。注意,一个CUDA内核就是一个可具备百万线程的并行程序,而这些内核函数更可以并行执行。
开普勒在内核函数执行引擎上比费米有了大幅度的加强。
从CUDA的发展角度看,NVIDIA一共经历了四代架构更新,而唯一不变的是warp硬件指令的宽度。(这里和AMD的稍微不同,后者硬件指令宽度是64)。

想要CUDA编程的童鞋可以开始了。安装好驱动、工具箱后,就可以安装C/C++编辑器了。用微软的Visual Studio比较方便,只是它本身不支持CUDA语法,需要在工具箱里面找到语法配置文件,配置一下就可以了。
其实,CUDA代码也不神秘,就是C和一些C的扩展而已,懂C的朋友很容易就明白了,不过CUDA代码编译的系统执行文件有点小小麻烦,因为需要调用2个编译器,一个是C/C++,另外一个是GPU编译器。还好NVDIA提供了比较方面的NVCC工具,这是一个半编译和连接工具,主要用语分离CPU和GPU代码,然后把CPU代码给VS编译,然后自己编译GPU代码。编译后连接好就可以编程执行代文件了。
这是NVIDIA的性能调试工具,非常不错,能够可视化分析硬件的使用率。
程序的产生都可以清楚分析,这是一个CUDA二维傅立叶变换的例子。不过计算单元的使用率不高,虽然很密集地运行kernel,但是每个kernel的执行时间不长,不到30微秒。
用性能工具来测试CUDA体渲染程序。
开普勒有多kernel并行运行的优势。
黄色感叹号表明程序可能有能够加强性能的改进之处。
载入粒子模拟仿真。
程序性能分析。
这一段小代码让GPU所有的CUDA核心都运行一个内循环加法。当然,真正的并行程序并没有那么简单。这里是主要是用性能工具来分析GPU ALU的使用率。
代码主要一一对应地生成1536个线程,每个线程做一个内循环,模拟GPU真实的负载工作。另外如果需要,可以调整Grid网格的规格增加线程,要生成一个百万线程,只需要在内核函数输入1000000/192=540个block线程块就可以了。GPU的最大优势是可以实现线程的高速切换,速度是CPU的上千到几千倍。
最后,技术宅跟我们分享了CUDA的一些感觉。CUDA是一个异构的执行体系,就是说CUDA里面你既要写CPU代码,也要内嵌GPU内核代码。它是用来发挥CPU、GPU两种架构的长处的。你认为CPU执行更好的部分,可以在函数用CPU代码实现;你认为某部分交给GPU执行跟好,就可以写成GPU代码。打个比方,某个负责引用需要一个并行度极高的运算和一个串行读很高的复杂运算构成,那就可以先通过PCI-E传输数据给GPU并行执行,然后返回给CPU做执行,最终输出结果。CUDA的另外一个用法是CUDA图形相互操作,比如支持PhysX物理加速的游戏就是,在图形渲染哪里和CUDA物理加速相互操作。
看到这里,是不是发现自己对CUDA有了更加深刻的认识?其实它也不是多么神秘的,就是个开发环境而已。



2#
发表于 2012-8-9 18:03 | 只看该作者
用CUDA的最大挑战是在数据计算的并行化设计和处理上,而搭建CUDA运行和开发环境只是很基础的东西。这人只是拿现有的CUDA粒子体验了一下,并没有真正的好好应用CUDA在实际工作里,所以顶多算是玩玩吧。
回复 支持 反对

使用道具 举报

3#
 楼主| 发表于 2012-8-9 18:13 | 只看该作者
nom8393 发表于 2012-8-9 18:03
用CUDA的最大挑战是在数据计算的并行化设计和处理上,而搭建CUDA运行和开发环境只是很基础的东西。这人只是 ...

实际设计程序很复杂的,CUDA只是提供个环境。
回复 支持 反对

使用道具 举报

4#
发表于 2012-8-9 18:14 | 只看该作者
这些疙瘩是不是都是C的 感觉java这边都扯不上干系 哎
回复 支持 反对

使用道具 举报

5#
发表于 2012-8-9 18:16 | 只看该作者
kylee82 发表于 2012-8-9 18:14
这些疙瘩是不是都是C的 感觉java这边都扯不上干系 哎

你可以去CUDA开发论坛问问有没有人为CUDA做JAVA的包,我估计是应该有。不过即使有Java的CUDA包,NV那个Nsight工具你也估计是用不了了,那样的话对程序的优化和调试都是大问题。所以还是建议用VC开发CUDA好一点。
回复 支持 反对

使用道具 举报

6#
发表于 2012-8-9 18:21 | 只看该作者
kylee82 发表于 2012-8-9 18:14
这些疙瘩是不是都是C的 感觉java这边都扯不上干系 哎

如必抠泥于语言,何况是java和c之间这么相像,java设计本意就是c++--.....
想java有一定水平,只看java语法也是不行的,是了解字节码的,java上主流的库都用到了动态字节码生成了...

回复 支持 反对

使用道具 举报

7#
发表于 2012-8-9 19:26 | 只看该作者
以前写个opencl字符串匹配算法,GPU优化了半天,还没CPU跑得快
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

广告投放或合作|网站地图|处罚通告|

GMT+8, 2025-2-9 12:07

Powered by Discuz! X3.4

© 2001-2017 POPPUR.

快速回复 返回顶部 返回列表