修改基本示例VECADD以使用共享内存

时间:2019-06-24 02:08:21

标签: cuda

我编写了以下内核,以将共享内存用于基本的CUDA示例vecadd(两个向量的总和)。该代码可以工作,但是内核执行所花费的时间与基本原始代码相同。有人可以建议我轻松地加快这种代码的速度吗?

__global__ void vecAdd(float *in1, float *in2, float *out,long int len) 
{
 __shared__ float s_in1[THREADS_PER_BLOCK];
 __shared__ float s_in2[THREADS_PER_BLOCK];

 unsigned int xIndex = blockIdx.x * THREADS_PER_BLOCK + threadIdx.x;

 s_in1[threadIdx.x]=in1[xIndex];
 s_in2[threadIdx.x]=in2[xIndex];

 out[xIndex]=s_in1[threadIdx.x]+s_in2[threadIdx.x];
}

1 个答案:

答案 0 :(得分:1)

  

有人可以建议我轻松地加快这种代码的速度

基本上没有对矢量加法这样的操作进行有用的优化。由于计算的本质,该代码只能希望达到50%的峰值算术吞吐量,并且每个FLOP需要进行三个内存事务,这使它成为内存带宽绑定操作。

结果是:

__global__ void vecAdd(float *in1, float *in2, float *out, unsigned int len) 
{
 unsigned int xIndex = blockIdx.x * blockDim.x + threadIdx.x;

 if (xIndex < len) {
  float x = in1[xIndex];
  float y = in2[xIndex];
  out[xIndex] = x + y;
 }
}

关于最新硬件上性能最佳的变体,例如,如果为最大占用选择了块大小,并且len足够大,例如:

  int minGrid, minBlockSize;
  cudaOccupancyMaxPotentialBlockSize(&minGrid, &minBlockSize, vecAdd);
  int nblocks = (len / minBlockSize) + ((len % minBlockSize > 0) ? 1 : 0);
  vecAdd<<<nblocks, minBlockSize>>>(x, y, z, len);