看到网上还有论坛好多刚开始接触CUDA编程的童鞋搞不清楚在GPU里blcok与thread到底是怎样排的,怎样才能通过索引准确找到,怎样在一个程序里怎样合理分配大小。这个博客就主要说一下这些问题吧,有不准确的地方欢迎同行指正! (1)先说一下CPU端数组的分配问题吧,经常看CUDA的童鞋可能会发现,基本上所有的CUDA程序无论是几维数组最后拷到GPU里用的都是一维数组,之前我也尝试过用二维数组,但是用起来真的特别麻烦而且容易出错,所以建议大家还是把数组转化为一维操作(顶级高手忽略); (2)对于线程和块的索引,很多书上感觉写的挺糊涂人的,个人觉得只要记住 blockIdx.x是块在X方向上的索引, blockIdx.y是块在Y方向上的索引, threadIdx.x是线程在X方向上的索引, threadIdx.y是线程在Y方向上的索引, blockDim.x是块在X方向上的线程数, blockDim.y是块在Y方向上的线程数, 然后再记住数据在GPU里是按照行优先排列的就OK啦 。比如分配一个二维block,每个blcok里面二维thread,那么线程索引就是 int row = blockIdx.x*blockDim.x + threadIdx.x; int col = blockIdx.y*blockDim.y + threadIdx.y; 绝对的偏移量: int offset=x+ y* blockDim.x*gridDim.x; //gridDim.x表示x方向有几个block。 (3)关于block和thread到底怎么分配的问题,注意不同的显卡每个block里面的线程是有限制的,具体大小还是要根据算法而定。比如乘法的瓦片技术里面,每个block计算一个瓦片,所以一个blcok内的线程数就是瓦片的大小,强烈建议大家好好写写乘法的优化程序还有三维矩阵的相乘,会受益颇多的。 |
|