加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

关于CUDA的简单的思考?

发布时间:2020-02-16 23:00:29 所属栏目:编程 来源:站长网
导读:在做CUDA开发的时候,感觉难点之一就是如何将GPU的性能发挥到最大。 比如说,在同学的GeForce 8400M GS上面跑的程式,Block数量可能要设置的比较少,也就是说一个thread粒度会比较大,这样才能发挥8400最大的性能,因为8400的SM数量 实在太少,但是相同的

在做CUDA开发的时候,感觉难点之一就是如何将GPU的性能发挥到最大。

比如说,在同学的GeForce 8400M GS上面跑的程式,Block数量可能要设置的比较少,也就是说一个thread粒度会比较大,这样才能发挥8400最大的性能,因为8400的SM数量 实在太少,,但是相同的程式设置用到GeForce GTX285上面却不好用了,为什么呢?因为GT300有30个SM,Block数目设置的较多一点才会更适合,thread的粒度相对较小。
尽管基本不会影响到程式的正确性,但是程式的优化却是和GPU不同不一样的,因此,Fermi做出了将32SP才集合成一个SM,而不是像以前的8个SP 组成一个SM,可能也是为了缓解该问题。
对比一下其他并行计算模型.

不过我对其他并行模型并没有多少了解,还请诸位高手指正。

在CUDA并行计算模型上面,一个程式每个thread的粒度都比较小,而且thread的总数一般都是10万个以上,同时众多thread组合成多个 block分批执行,因此在一个block内thread的计算量和任务基本都是高度一致的(否则会引起很显著的性能问题),因此也不适合做分支预测很多 的任务。

在x86的CPU上面的OpenMP以及Windows SDK的thread管理和模型,每个thread的粒度相对于CUDA来说都是远远大于。同时thread的总数也会比较少,因为thread过多 thread切换带来的时间开销会比较显著,同时每个thread之间可以按照自己的路线走下去,对于分支预测来说也比较适合。

MPI和Stream没有了解过,不熟悉,抱歉。
比较一下共享数据的操作.

在无论是OpenMP还是Windows SDK里面的并行计算中,对共享变量的操作(主要是涉及到写入)的时候,一般都是依靠Lock机制或者Atomic操作机制.
比如创建了两个thread,这两个thread同时要对变量i进行写入的操作,那么就遇到了共享数据问题,CPU并行常见的做法是 Lock,将该变量Lock住,这个时间段内只能有一个thread对其操作,另外一个thread则处于等待状态,直到等到那个thread给变量 Unlock之后才行.
因此这里有时也会遇到死锁问题,程式设计师可能一时疏忽,忘记了Unlock,那么另外一个thread则不停的处于等待状态.

CUDA对此的做法则是有很大的不同,CUDA的并行机制难以忍受如此的Lock操作,因为对一个thread来说实在是太耗时间了,CUDA里面的 thread数量通常都是10万个以上,假如thread都去Lock和Unlock,那么时间开销实在太巨大了.
因此CUDA借助GPU得天独厚的硬体属性,依靠存储器的属性来避免这个问题,比如说GPU里面有shared memory,这个是一个Block内的thread都可以读写的,还有global memory,这个是允许所有thread读写的,每个thread还有自己私有的register,只允许自己读写,此外还有只能读的constant memory和texture memory,依靠着block ID和thread ID的不同来避开共享数据的读写冲突.

当然,有时的无法避免,因此CUDA在1.1版本中加入了Atomic操作,但是目前来看,G92等等GPU的atomic操作会带来很明显的性能降 低,GT200 GPU性能降低仍然比较明显,期待Fermi能够带来很多改善

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读