我有一个非常简单的算法,可以计算两个矩阵的相应行之间的平方欧几里德距离。我有以下代码,但不幸的是,它不会为不同的矩阵大小返回正确的结果。更具体地讲,它工作正常大小2000x4
,500x4
,2500x2
,600x8
,1000x8
,100x8
的矩阵,但它是不工作的大小2500x3
,2500x5
,400x3
,100x3
,100x10
,1000x10
,1000x12
,500x12
,500x14
的矩阵。使用CUDA计算矩阵的相应行之间的欧几里得距离
任何人都可以帮助我吗?我想手动执行,而不使用任何优化库,因为我想了解线程管理。
__global__ void cudaEuclid(float* A, float* B, float* C, int rows, int cols)
{
int i, squareeucldist = 0;
int r = blockDim.x * blockIdx.x + threadIdx.x; // rows
int c = blockDim.y * blockIdx.y + threadIdx.y; // cols
extern __shared__ float sdata[];
//int r = blockIdx.y; int c = threadIdx.x;
if(r < rows && c < cols ){
//C[r + rows*c] = (A[r + rows*c] - B[r + rows*c]) * (A[r + rows*c] - B[r + rows*c]);
sdata[threadIdx.x] = (A[r + rows*c] - B[r + rows*c]) * (A[r + rows*c] - B[r + rows*c]);
__syncthreads();
// contiguous range pattern
for(int offset = blockDim.x/2;
offset > 0;
offset >>= 1)
{
if(threadIdx.x < offset)
{
// add a partial sum upstream to our own
sdata[threadIdx.x] += sdata[threadIdx.x + offset];
}
// wait until all threads in the block have
// updated their partial sums
__syncthreads();
}
// thread 0 writes the final result
if(threadIdx.x == 0)
{
C[r] = sdata[0];
}
}
}
内核调用是:
dim3 dimBlock(cols, 1);
dim3 dimGrid(1, rows);
cudaEuclid<<<dimGrid, cols, cols*sizeof(float)>>>(d_A, d_B, d_C, rows, cols);
PS:我想提一提,我已经发布了类似的问题,但它是从一开始就不清,讨论是无所适从。尽管Tom提出了一个非常有用的建议,认为未来优化实施将非常实用,但我需要更多的手工制作。最后,我发表这篇文章的原因是因为我不想让相关文章更加复杂。谢谢。
您测试过60x8吗?或者您在60x5时停止了吗?奇数列似乎没有正确处理。或者甚至可能是2的给予'偏移>> = 1'的非幂... – chappjc
它正在为60x8工作。 – Darkmoor
有道理,这就是问题所在,尽管Eric给出了一个完整的答案。 – chappjc