这段CUDA程序中的模型是 一个GPGPU有多个Block,每个block有blockDim.x纬, 后面是该block线程的序号
a[tid] = tid;
CUDA程序后面的部分还没看到,请教两个问题:
1 a[tid] = tid; 这种方式是数组中的值等于线程号,怎么能够通过后面的规约,得到1到n的加和呢。
2 如果是a[tid] = tid ,会不会像普通的C++程序一样,数组中有很多量是没有被赋值的。
这段CUDA程序中的模型是 一个GPGPU有多个Block,每个block有blockDim.x纬, 后面是该block线程的序号
a[tid] = tid;
CUDA程序后面的部分还没看到,请教两个问题:
1 a[tid] = tid; 这种方式是数组中的值等于线程号,怎么能够通过后面的规约,得到1到n的加和呢。
2 如果是a[tid] = tid ,会不会像普通的C++程序一样,数组中有很多量是没有被赋值的。
这2个问题本来不想回答的。因为你丝毫没有看任何关于CUDA的资料。任何看完了《CUDA C Progamming Guide》的前言的人都会理解这个问题。而手册的解释十分基础而且详细,比你问问题然后等待版主解答的效果好10倍。
但是既然问了,依然回答吧。虽然你有更容易得到,更容易理解的方式不去看。却选择了提问。
(1)对于“a[tid] = tid; 这种方式是数组中的值等于线程号,为何以后却可以规约得出1+…+n”。
—这个问题本身就是错误的。错误有2点。
(1-a) “这种方式是数组中的值等于线程号” – 这实际上是数组中为下标n的元素,值被设置成n. 因为你的线程需要是从0到n-1(你的if(tid < n)处),所以这个数组被填充满0,1,2,3…,n-1。
(1-b) "为何能得到1到n的加和呢?” – 不能,你只能得到0到n-1的加和,而不是1到n的。因为该假设是错误的,所以无需为你阐述为何能计算1加到n。
(2)“如果是a[tid] = tid ,会不会数组中有很多量是没有被赋值的。”–依然是前文的描述,不会的,因为你不是1个线程,你有一堆线程。如果不能理解这点,请简单翻阅一下手册的《前言》。里面有丰富的插图,帮助你理解。
我的老乡说过一段话:
只埋头学习,而不思考,你会感到迷茫;
只整天空想,而不学习,你会感到痛苦。
不要迷茫,不要痛苦,让我和楼主共勉吧。
是不是这样理解:
(nBlocks-1)nThreadsPerBlock<N<=nBlocksnThreadsPerBlock 把数组平均分配到每个GPGPU单元
thrust::reduce 的归约 就是先内部加和再所有单元加和
首先说,不是将数组分配给每个“GPGPU”。 你可以这么理解,将对数组赋值的任务,分散给多个GPU的计算单元(SM)。我还是建议你看一眼手册,没坏处的。
其次:
int nBlocks = n/nThreadsPerBlock + ((n % nThreadsPerBLock) ? 1: 0);
这里实际上是:
int nBlocks;
if (n % nThreadsPerBlock == 0) nBlocks = n / nThreadsPerBlock;
else nBlocks = n / nThreadsPerBlock + 1;
举个具体例子,你的数组有1025个元素,每个线程负责1个元素赋值,而你一个block有256个线程,那么你需要多少个blocks? 是4个吗?不是,是5个,需要+1,只要没正好。
再举个例子,如果你有512个元素,此时就不需要+1了。因为2个blocks正好可以。
对您最后的这个问题,“thrust::reduce 的归约 就是先内部加和再所有单元加和”,我表示无法理解。原因有2,(1)是我的中文水平不足以理解。(2)我不是C++用户。
我建议其他版主/会员回答您的最后一段问题。
感谢您的来访,
预祝春节愉快。
对二位楼主的耐心和学问赞一个啊
预祝春节愉快,阖家团圆~
能够为您服务是我们的荣幸!