RT,这几天开始试着改编以前的C程序,想把中间有一部分在四维空间查表的代码用CUDA来跑。由于涉及到4个参数以及边界、步长,如果每个thread内对这四个参数都进行查找,那么所需寄存器个数肯定超过20,也就不能使GPU达到满载(C2050)。
前面有点废话了,说正题。 我的疑惑在于如果给thread分配任务,下面是两个比较极端的例子:
方法1: Host代码采用多层循环设定好子空间,然后采用多个stream异步执行相同的kernel。由于子空间参数已经分配,此时每个thread无需再根据blockID或者threadID来确定子空间。(这个思路是受到新的cudaCreateStreamWithFlags命令的启发)
方法2:host代码不事先分配好子空间,直接运行kernel,在kernel内部根据blockID和threadID来确定各自的子空间。
这两种方法是否都可行? 如果都可行,哪个效率会好一些呢?
谢谢大家!
楼主您好!
您的前提假设:“那么所需寄存器个数肯定超过20,也就不能使GPU达到满载(C2050)”不成立哦!
而您的问题实际上和您的前提无关。
对于您的问题,我觉得都行。只要你的多个stream对GPU的任务发布能够及时,不让GPU空闲,那么一样可以GPU全负荷工作。后者也没问题,只要你不觉得麻烦。
BZ你好,我是这么计算的:C2050每个SM上只有32768个寄存器,同时每个SM最多同时跑1536个thread,所以每个thread最多能分到20个寄存器。
这样计算不对么?
楼主你好。
你这么算的结果是正确的,但如果将这个结果套用到1楼的假设中,则不成立。
因为您试图理解:只有上1536个线程/2.0的SM, 才能让SM满负荷工作是不对的。
因为需要证明/证伪您的这理论的正确性很简单,因为只需要找到一个反例:有人可以只用2个warp就让GPU load 100%. 这才64个线程。
您可以这么说,1个SM上的线程越多,SM越不容易空闲。但您不能说“上1536个线程,才能满载。因为要上这么多线程,所以我不能用多于21个寄存器。”

或者您的意思是说,像我那样子查找一个四维空间,寄存器不会轻松超过20?
请仔细阅读上文!
我表示反对的内容已经明确的表达过了,是你的“需要寄存器超过20个,则GPU不能满载”的说法。
这个数字计算的当然没错,但这里面有两点需要说明:
1:您的代码最后究竟每个线程使用了多少寄存器,这个是编译器决定的,而编译器是比较智能的。所以人为估计使用了多少寄存器往往是不准确的,建议您跑profiler看看。
2:即使是没有跑到最大线程数,确切地说,并不代表一定无法发挥GPU的全部效能。有使用较少线程数而达到很好效果的例子。
神马,你不是反复说过,要尽量上满线程数量的么?
是的,不过这只是一般的建议,这只是尽量挖掘GPU能力的一个手段。如果铺上去一堆线程,问题就解决了,那自然不用考虑其他。但如果线程数量较少,但是依然足够GPU掩盖各种延迟,GPU能够满负荷工作,那么也是完全OK的。
说一千道一万,其实您可以先按照您的初步想法写个kernel,跑跑profiler,看看寄存器占用率究竟如何,看看GPU有没有满载运行。也许真实情况和您设想的会有所差别,到时候无论是优化实现,还是修改算法,都更加明确。
建议大致如上,祝您编码愉快~
哇,2个warp就让GPU满载! 能否给个链接呢,我想学习一下。
是不是如果thread都主要用来运算,而不需要很多I/O操作,使无谓的延迟消减到一定程度的话,那么少量线程也就可以让GPU满载工作?
但thread的数目至少要比sp的个数多吧?
多谢! 我也是想练习练习在写代码时就多考虑优化的问题, 只有自己开始写代码才觉得GPU内部构造真麻烦。
同时,继续刚才问题: GPU满载时,thread数量至少不能比sp数量少吧?
system
10
链接无法提供。这只是为了反对你的1楼的"要满载,不能用>20个寄存器而已“。
至于您的第二个问题,在2.0上需要至少多少线程,才能让SP都不空闲?
我想您需要2个至少warp,也就是至少64个线程。
system
11
我不建议您这样。
边写代码边优化不是好行为,建议您先写完,调试正确。
然后在保持程序逻辑不变的情况下,进行优化。
system
12
我用的C2050 Tesla卡, 一共有14*32=448个sp。我实在想不通64个thread就能让所有sp都忙活起来。能否给点提示呢? 谢谢
system
13
您在偷换概念!
您一直强调1536个线程才行,自然让人理解为针对1个SM而说的,或者针对只有1个SM的GPU而说的。
所以我自然也回答64,而不是回答64*N (N是贵卡的SM个数)。