我陷入了一件非常简单的事情,我需要一个意见。我在CUDA中有一个非常简单的内核,它复制了两个数组之间的元素(我有理由这样做)和
__global__
void kernelExample( float* A, float* B, float* C, int rows, int cols )
{
int r = blockIdx.y * blockDim.y + threadIdx.y; // vertical dim in block
int c = blockIdx.x * blockDim.x + threadIdx.x; // horizontal dim in block
if ( r < rows && c < cols) {
// row-major order
C[ c + r*cols ] = A[ c + r*cols ];
}
//__syncthreads();
}
我的结果令人不满意。有什么建议吗?
内核的调用如下:
int numElements = rows * cols;
int threadsPerBlock = 256;
int blocksPerGrid = ceil( (double) numElements / threadsPerBlock);
kernelExample<<<blocksPerGrid , threadsPerBlock >>>( d_A, d_B, d_C, rows, cols );
已更新(在Eric的帮助下):
int numElements = rows * cols;
int threadsPerBlock = 32; //talonmies comment
int blocksPerGrid = ceil( (double) numElements / threadsPerBlock);
dim3 dimBlock( threadsPerBlock,threadsPerBlock );
dim3 dimGrid( blocksPerGrid,blocksPerGrid );
kernelExample<<<dimBlock, dimBlock>>>( d_A, d_B, d_C, rows, cols );
例如具有矩阵A
A =[
0 1
2 1
0 2
0 0
2 0
0 1
2 1
2 2
2 2
0 0
2 1
2 2
3 1
2 2
2 2
]
返回的矩阵C是
C = [
0 1
2 1
0 2
0 0
2 0
0 1
2 1
2 2
2 2
0 0
2 1
2 2
3 1
2 2
2 2
]
答案 0 :(得分:1)
默认情况下,C / C ++使用基于0的索引。
尝试
1)从
改变 if ( r <= rows && c <= cols) {
到
if ( r < rows && c < cols) {
2)del __syncthreads();
因为你没有在线程之间共享数据
3)将块和网格设置从1-D更正为2-D,因为在内核中同时使用.x
和.y
4)如果您不使用它,请删除float* B
。
解决问题。
有关详细信息,请参阅cuda示例代码中以下文件中的内核copy()
。
$CUDA_HOME/samples/6_Advanced/transpose/transpose.cu