使用CUDA共享内存改进全局访问模式
我使用以下内核来获得一组向量的大小:使用CUDA共享内存改进全局访问模式,cuda,shared-memory,Cuda,Shared Memory,我使用以下内核来获得一组向量的大小: __global__ void norm_v1(double *in, double *out, int n) { const uint i = blockIdx.x * blockDim.x + threadIdx.x; if (i < n) { double x = in[3*i], y = in[3*i+1], z = in[3*i+2]; out[i] = sqrt(x*x + y*y
__global__ void norm_v1(double *in, double *out, int n)
{
const uint i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < n)
{
double x = in[3*i], y = in[3*i+1], z = in[3*i+2];
out[i] = sqrt(x*x + y*y + z*z);
}
}
然而,当
n%blockDim.x!=0
,需要事先知道最大块DIM
,并在使用n=1024
进行测试时,为out[i>255]
生成不正确的结果。我应该如何最好地解决这个问题?我认为这可以解决out[I>255]
问题:
__shared__ double shIn[3*BLOCKDIM];
const uint blockStart = blockIdx.x * blockDim.x;
invec[0*blockDim.x+threadIdx.x] = in[ blockStart*3 + 0*blockDim.x + threadIdx.x];
invec[1*blockDim.x+threadIdx.x] = in[ blockStart*3 + 1*blockDim.x + threadIdx.x];
invec[2*blockDim.x+threadIdx.x] = in[ blockStart*3 + 2*blockDim.x + threadIdx.x];
__syncthreads();
double x = shIn[3*threadIdx.x];
double y = shIn[3*threadIdx.x+1];
double z = shIn[3*threadIdx.x+2];
out[blockStart+threadIdx.x] = sqrt(x*x + y*y + z*z);
至于n%blockDim.x!=0
我建议用0填充输入/输出数组,以符合要求
如果您不喜欢BLOCKDIM
宏,请使用extern\uuuuuu shArr[]
进行探索,然后将第三个参数传递给内核配置:
norm_v2<<<gridSize,blockSize,dynShMem>>>(...)
它基本上将任何数组视为int
-s的数组,并将数据从一个位置复制到另一个位置。如果仅使用64位类型,则可能需要将基础的int
类型替换为double
-s或long-long int
然后可以将复制行替换为:
memCopy(invec, in+blockStart*3, min(blockDim.x, n-blockStart));
我认为这可以解决
out[I>255]
问题:
__shared__ double shIn[3*BLOCKDIM];
const uint blockStart = blockIdx.x * blockDim.x;
invec[0*blockDim.x+threadIdx.x] = in[ blockStart*3 + 0*blockDim.x + threadIdx.x];
invec[1*blockDim.x+threadIdx.x] = in[ blockStart*3 + 1*blockDim.x + threadIdx.x];
invec[2*blockDim.x+threadIdx.x] = in[ blockStart*3 + 2*blockDim.x + threadIdx.x];
__syncthreads();
double x = shIn[3*threadIdx.x];
double y = shIn[3*threadIdx.x+1];
double z = shIn[3*threadIdx.x+2];
out[blockStart+threadIdx.x] = sqrt(x*x + y*y + z*z);
至于n%blockDim.x!=0
我建议用0填充输入/输出数组,以符合要求
如果您不喜欢BLOCKDIM
宏,请使用extern\uuuuuu shArr[]
进行探索,然后将第三个参数传递给内核配置:
norm_v2<<<gridSize,blockSize,dynShMem>>>(...)
它基本上将任何数组视为int
-s的数组,并将数据从一个位置复制到另一个位置。如果仅使用64位类型,则可能需要将基础的int
类型替换为double
-s或long-long int
然后可以将复制行替换为:
memCopy(invec, in+blockStart*3, min(blockDim.x, n-blockStart));