__global__ void sum(const float * __restrict__ indata, float * __restrict__ outdata) {
unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x;
// --- Specialize BlockReduce for type float.
typedef cub::BlockReduce<float, BLOCKSIZE> BlockReduceT;
// --- Allocate temporary storage in shared memory
__shared__ typename BlockReduceT::TempStorage temp_storage;
float result;
if(tid < N) result = BlockReduceT(temp_storage).Sum(indata[tid]);
// --- Update block reduction value
if(threadIdx.x == 0) outdata[blockIdx.x] = result;
return;
}
我已经成功测试了cuda cub的缩减总和(如上面的代码片段所示),我想根据这段代码执行两个向量的内积。但我对它有一些困惑:
我们需要内部产品的两个输入向量,需要我在得到的新向量的减少和之前对这两个输入向量进行分量乘法。
在cuda cub的代码示例中,输入向量的维数等于blocknumber * threadnumber。如果我们有一个非常大的向量怎么办。
答案 0 :(得分:1)
是的,对于cub,假设你的向量是分开存储的(即不是交错的),你需要先进行逐元素乘法。另一方面,推力transform_reduce可以在单个函数调用中处理它。
blocknumber * threadnumber应该为您提供所需的所有范围。在cc3.0或更高版本的GPU上,块编号(即gridDim.x
)的范围最大可达2 ^ 31-1,线程编号(即blockDim.x
)最大可达1024.这使您可以处理2 ^ 40个元素。如果每个元素是4个字节,则这将构成(即需要)2 ^ 42个字节。这大约是4TB(如果考虑2个输入向量,则为两倍),这比目前的任何GPU内存都要大得多。因此,在用完网格维度之前,您将耗尽GPU内存空间。
请注意,您展示的内容为cub::BlockReduce
。但是,如果您正在使用两个大向量的矢量点积,则可能需要使用cub::DeviceReduce
。