我正在执行矢量点产品(A×B)的Cuda内核。我假定每个向量的长度是32(32,64,...)的倍数,并且将块大小定义为等于数组的长度。块中的每个线程都将A的一个元素与B的相应元素相乘(线程i ==> psum = A [i] xB [i])。在乘法之后,我使用了使用warp shuffling技术执行还原的以下函数,并计算所有乘法的和。经纱洗牌,以减少任何长度的阵列
__inline__ __device__
float warpReduceSum(float val) {
int warpSize =32;
for (int offset = warpSize/2; offset > 0; offset /= 2)
val += __shfl_down(val, offset);
return val;
}
__inline__ __device__
float blockReduceSum(float val) {
static __shared__ int shared[32]; // Shared mem for 32 partial sums
int lane = threadIdx.x % warpSize;
int wid = threadIdx.x/warpSize;
val = warpReduceSum(val); // Each warp performs partial reduction
if (lane==0)
shared[wid]=val; // Write reduced value to shared memory
__syncthreads(); // Wait for all partial reductions
//read from shared memory only if that warp existed
val = (threadIdx.x < blockDim.x/warpSize) ? shared[lane] : 0;
if (wid==0)
val = warpReduceSum(val); // Final reduce within first warp
return val;
}
我只是简单地调用blockReduceSum(psum)psum是线程乘以两个元素。
当数组的长度不是32的倍数时,此方法不起作用,所以我的问题是,我们可以更改此代码,以便它也适用于任何长度?或者它是不可能的,因为如果数组的长度不是32的倍数,那么一些warp的元素属于多个数组?