有一个四维矩阵大小为A[9][9][300][400],首先将其按照一定顺序转化为一个1D数组,现在想做的一个运算求一新的数组B,其维数大小与 A相同,B的任一元素与 A的关系可以表述为 B[m][n][y]=A[(m+4)%9][(n+4)%9][(x+150)%300][(y+200)%400],dimBlock和dimGrid如何设置才好,thread的索引如何与原矩阵的角标对应起来呢?新手入门,求助大家啦,现在已经被绕晕了,希望有人能指点迷津啊,多谢了!
LZ您好:
您的问题有多种不同的方法都可以解决,因为这里A,B都是C语言风格的行优先存储的数组,其一维化的方法是固定的,此时不妨完全按照一维化以后的方式安排线程:
每个线程完成B的一个元素的求解。
每个block选择典型的256线程或者192线程即可,安排grid中block按照一维排布,并且使得总的线程数量超过您A中的元素数。
然后在kernel中计算每个线程的一维化的总的tid,将超出元素数的部分return。
剩下的线程就地反求出自己的对应的坐标m,n,x,y,然后按照您的赋值公式赋值即可。
这种方法的好处是完全无需考虑线程block的具体形状和安排,缺点是,会引入一些多余的计算。
此外,您还可以使用一维的block,每个block 400个线程,每个block对应您矩阵中的一行。
然后grid中排布block来对应剩下的3个维度
gridDim.x取300,也就是倒数第二个维度参数,gridDim.y对应9,倒数第三个维度参数,gridDim.z对应9,也就是第一个维度参数。
这样您每个线程可以直接通过threadIdx.x,blockIdx.x,blockIdx.y,blockIdx.z来分别得到您的y,x,n,m这四个坐标参数,然后直接按照您的公式对B赋值即可。
以及,实现方法并不唯一,这只是为您示例而已。
祝您好运~
版主您好:
如果按照第一种的话,您看我以下设置是否正确,dimgrid((99300400+256-1)/256,1,1),tid=threadIdx.x+blockIdx.xblockDim.x,反求出对应m,n,x,y坐标这部分还有赋值部分您能给出公式来吗,对线程和坐标之间的对应关系还有些迷糊?
LZ您好:
1:这个是正确的。
2:请您自己推算一下,可以找个2维问题先考虑,您自己想出来的话,效果较好。
祝您好运~
是不是根据tid和数组存放的方式来推出来,我推的结果是m=tid/(3004009),n=(tid-m3004009)/(300400),x=(tid-m3004009-n300*400)/400,…您看是不是这个思路
LZ您好:
您自己推导出来的方法是正确的,恭喜您~
祝您好运~
赋值那部分的话,是不是我根据求出来的m,n,x,y,求出A所对应的m’,n’,x’,y’,然后将m’,n’,x’,y’写成这种形式tid’=y’+x’*400…,最后用b[tid]=a[tid’]赋值即可呢?
[
LZ您好:
当你一个确定的线程计算得到了自己的m,n,x,y之后,对应的m’,n’,x’,y’是立即可以知道的,直接用m’,n’,x’,y’作为坐标访问A即可。
您可以考虑按照一维化的形式访问A和B,当然按照多维形式也可以,直接把您的1#的等式写进去即可。(这要求这里的指针是带有维度信息的)
大致如此,祝您好运~
恩,多谢版主了哈
LZ您好:
不客气的,您也不妨试一下其他的方法,以加深理解。
祝您好运~