我编写了以下内核,以将共享内存用于基本的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];
}
答案 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);