基于并行约简优化内核函数

时间:2013-10-02 20:10:29

标签: cuda parallel-processing gpu

在我之前的一篇文章中,我问过如何改进内核函数。内核计算两个相等大小的矩阵的相应行之间的欧氏距离平方。 Eric 给出了一个非常好的提示,即每行使用一个线程块,之后应用并行缩减。在继续进一步细节之前,这篇文章是因为我不想让上一篇文章变得更复杂,我要感谢 Eric 。下面我附上.cu代码,但没有给我正确的结果。

__global__ void cudaEuclid( float* A, float* B, float* C, int rows, int cols )
{
    extern __shared__ float sdata[];

    unsigned int tid = threadIdx.x;
    unsigned int c = blockDim.x * blockIdx.x + threadIdx.x; // rows
    unsigned int r = blockDim.y * blockIdx.y + threadIdx.y; // cols


    sdata[ tid ] = ( A[ r*cols + c ] - B[ r*cols + c ] ) * ( A[ r*cols + c ] - B[ r*cols + c ] );

    __syncthreads();

    for ( unsigned int s = 1; s < blockDim.x; s*=2 ){
        if ( tid % (2*s) == 0 ){
            sdata[ tid ] += sdata[ tid + s ];
        }
    }
    __syncthreads();

    if ( tid == 0) C[blockIdx.x]=sdata[0];  
}

代码基于http://developer.download.nvidia.com/compute/cuda/1.1-Beta/x86_website/projects/reduction/doc/reduction.pdf。它不是优化版本。我只是想抓住基本点。我认为我初始化sdata时存在问题。内核的初始化也是通过这种方式完成的:

int threadsPerBlock = 256;  
int blocksPerGrid = ceil( (double) numElements  / threadsPerBlock);

dim3 dimBlock(1, threadsPerBlock); 
dim3 dimGrid(blocksPerGrid, 1); 

cudaEuclid<<<dimGrid, dimBlock>>>( d_A, d_B, d_C, rows, cols );

谢谢你,对不起我感到抱歉。

2 个答案:

答案 0 :(得分:3)

您正在使用动态分配的共享内存,但实际上并没有分配任何共享内存。内核启动应该有一个额外的参数,用于每个块的共享内存大小。

cudaEuclid<<<dimGrid, dimBlock, threadsPerBlock*sizeof(float)>>>( d_A, d_B, d_C, rows, cols );
  • 考虑使用CUB进行缩减 - 让您免于从头开始重新实现并进行调整。
  • 如果你想自己编写代码,那么这个例子的more recent version比CUDA 1.1-beta的版本好!

答案 1 :(得分:0)

sdata [tid] + = sdata [tid]; ==&GT;你只是两次添加相同的值 你需要做什么

sdata [tid] + = sdata [tid + s]