在CUDA内核中的数组之间移动元素

时间:2013-10-06 20:37:46

标签: cuda parallel-processing gpu

我陷入了一件非常简单的事情,我需要一个意见。我在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
]

1 个答案:

答案 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