在CUDA中的块之间分配线程
我在CUDA做一个项目。第一次我只使用了一个带有在CUDA中的块之间分配线程,cuda,Cuda,我在CUDA做一个项目。第一次我只使用了一个带有Dim 8*8的块作为矩阵。然后我计算指数如下: int idx = blockIdx.x * blockDim.x + threadIdx.x; int idy = blockIdx.y * blockDim.y + threadIdx.y; 它给了我一个正确的答案。之后,我想在块之间分配线程以测量性能。我使网格变暗为(2,1),块变暗为(4,8) 当我手工调试代码时,它似乎在不更改上述公式的情况下为我提供了正确的索引。但是当我运行程序
Dim 8*8
的块作为矩阵。然后我计算指数如下:
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int idy = blockIdx.y * blockDim.y + threadIdx.y;
它给了我一个正确的答案。之后,我想在块之间分配线程以测量性能。我使网格变暗为(2,1),块变暗为(4,8)
当我手工调试代码时,它似乎在不更改上述公式的情况下为我提供了正确的索引。但是当我运行程序时,屏幕挂起,结果都是零
我做错了什么,我该如何解决
这是内核函数
__global__ void cover_fault(int *a,int *b, int *c, int *d, int *mulFV1, int *mulFV2, int *checkDalU1, int *checkDalU2, int N)
{
//Fig.2
__shared__ int f[9][9];
__shared__ int compV1[9],compV2[9];
int dalU1[9] , dalU2[9];
int Ra=2 , Ca=2;
for (int i = 0 ; i < N ; i++)
for (int j = 0 ; j < N ; j++)
f[i][j]=0;
f[3][0] = 1;
f[0][2] = 1;
f[0][6] = 1;
f[3][7] = 1;
f[2][4] = 1;
f[6][4] = 1;
f[7][1] = 1;
int t =0 ,A = 1,B = 1 , UTP = 5 , LTP = -5 , U_max = 40 , U_min = -160;
bool flag = true;
int sumV1, sumV2;
int checkZero1 , checkZero2;
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int idy = blockIdx.y * blockDim.y + threadIdx.y;
while ( flag == true)
{
if ( c[idy] == 0 )
compV1[idy] = 1;
else if ( c[idy]==1)
compV1[idy] = 0 ;
if ( d[idy] == 0 )
compV2[idy] = 1;
else if ( d[idy]==1 )
compV2[idy] = 0 ;
sumV1 = reduce ( c, N );
sumV2 = reduce ( d, N );
if (idx<N && idy <N)
{
if(idx==0)
mulFV1[idy]=0;
if(idy==0)
mulFV2[idx]=0;
__syncthreads();
atomicAdd(&(mulFV1[idy]),f[idy][idx]*compV2[idx]);
atomicAdd(&(mulFV2[idx]),f[idy][idx]*compV1[idy]);
}
dalU1[idy] = ( -1*A*( sumV1 - Ra )) + (B * mulFV1[idy] * compV1[idy]) ;
dalU2[idy] = ( -1*A*( sumV2 - Ca )) + (B * mulFV2[idy] * compV2[idy]) ;
a[idy] = a[idy] + dalU1[idy];
b[idy] = b[idy] + dalU2[idy];
if ( a[idy] > U_max )
a[idy] = U_max;
else
if (a[idy] < U_min )
a[idy] = U_min;
if ( b[idy] > U_max )
b[idy] = U_max;
else
if (b[idy] < U_min )
b[idy] = U_min;
if (dalU1[idy]==0)
checkDalU1[idy]=0;
else
checkDalU1[idy]=1;
if (dalU2[idy]==0)
checkDalU2[idy]=0;
else
checkDalU2[idy]=1;
__syncthreads();
checkZero1 = reduce(checkDalU1,N);
checkZero2 = reduce(checkDalU2,N);
if ( checkZero1==0 && checkZero2==0)
flag = false;
else
{
if ( a[idy] > UTP )
c[idy] = 1;
else
if ( a[idy] < LTP )
c[idy] = 0 ;
if ( b[idy] > UTP )
d[idy] = 1;
else
if ( b[idy] < LTP )
d[idy] = 0 ;
t++;
}//end else
sumV1=0;
sumV2=0;
mulFV1[idy]=0;
mulFV2[idy]=0;
} //end while
}//end function
\uuuuuuuuuuuuuuuuuuuuu全局\uuuuuuuuuuuuuuuu无效覆盖层\uuuuuuuuuuuuuuuuu故障(int*a、int*b、int*c、int*d、int*mulFV1、int*mulFV2、int*checkDalU2、int-N)
{
//图2
__共享_uu_uu_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u;
__共享_uu_uu_uu_uu_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u_u;
int-dalU1[9],dalU2[9];
int Ra=2,Ca=2;
对于(int i=0;iUTP)
c[idy]=1;
其他的
if(a[idy]UTP)
d[idy]=1;
其他的
如果(b[idy]
在索引计算中,idx
将为您提供列索引和行索引。您是否以M[idy][idx]
的身份访问矩阵
cuda线程按照正交系统组织:X为水平,Y为垂直。因此,如果你说实际矩阵中的点M[0][1],那么它就是M[1][0]。如果你想得到答案,请发布一些实际代码。否则,您的问题将归结为“我的程序不起作用,为什么?”。你不能指望有人能回答这个问题,是吗?@Talonmes我的代码有300多行,我一直在玩代码,直到我确定问题出在我有超过1个块的时候,大多数代码都是数学语句。@asma-然后删除数学,只需传入和传出数据,直到您得到正确传递数据的多块场景。如果您自己没有发现问题,请发布简化的代码。那么,数学bsck应该很简单。@SteveFallows谢谢你的建议,我对整个代码进行注释,并将上面的索引结果打印出来。索引是对的。@Talonmes:这是一个归约函数,添加行或列的元素。。我从SDK中获得了它,并做了一些修改欢迎Tudor,idx将给我行,idy将给我列。是的,我想访问2D数组,我之前对它进行了测试,并给出了正确的结果。@asma:idx将给出列,而不是行,并对行进行idy。试着扭转它们,看看会发生什么。记住,在一个正交系统上,X是水平轴,Y是垂直轴。我交换了X和Y的索引。但它仍然给了我同样的问题。。hang和zeros:(感谢您的支持,我将在回答中发布我的代码以澄清问题。我通过更改数组的大小和迭代次数来调试我的代码,我发现它在某个点上卡住了,我想是因为内存问题。这是个例外(第一次机会例外在Move.exe 0x75 28 9617:微软C++异常:CUAAYRORGNONEM在内存位置0x00 12F81C…..)有什么想法吗?