我正在尝试使用此代码对数组求和,而且我被卡住了。我可能需要一些“CUDA for dummies tutorial”,因为我花了很多时间进行这样的基本操作而且我无法使它工作。
以下列出了我不理解或不确定的事项:
我应该使用多少块(dimGrid)?
我认为应该是N/dimBlock.x/2
(N =输入数组的长度),因为在内核的开头,数据被加载并从全局内存的两个“块”添加到共享内存
原始代码中有blockSize
。我用blockDim.x
替换它,因为我不知道这些变量是如何不同的。但是当blockSize
= blockDim.x
时,gridSize = blockDim.x*2*gridDim.x
对我没有意义 - gridSize
将大于N. * Dim.x和*之间有什么区别?在一维数组的上下文中的大小?
主逻辑 - 在内核中,每个块总和2 * dimBlock(块中的线程)数。当N = 262144且dimBlock = 128时,内核返回1024个部分和数组。然后我再次运行内核,结果= 4个部分总和。最后,在上一次运行中,返回单个sum,因为数组由单个块处理。
我求和二进制数组。在第一次运行中,我可以使用uchar4
作为输入数据。在第二次和第三次运行中,我将使用int
。
请告诉我,我错过了什么
由于
__global__ void sum_reduction(uchar4* g_idata, int* g_odata, int N) {
extern __shared__ int s_data[];
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*(blockDim.x*2) + tid;
unsigned int gridSize = blockDim.x*2*gridDim.x;
while (i < N) {
s_data[tid] += g_idata[i].x + g_idata[i+blockDim.x].x +
g_idata[i].y + g_idata[i+blockDim.x].y +
g_idata[i].z + g_idata[i+blockDim.x].z +
g_idata[i].w + g_idata[i+blockDim.x].w;
i += gridSize;
}
__syncthreads();
if (tid < 64) {
s_data[tid] += s_data[tid + 64];
}
__syncthreads();
if (tid < 32) {
volatile int *s_ptr = s_data;
s_ptr[tid] += s_ptr[tid + 32];
s_ptr[tid] += s_ptr[tid + 16];
s_ptr[tid] += s_ptr[tid + 8];
s_ptr[tid] += s_ptr[tid + 4];
s_ptr[tid] += s_ptr[tid + 2];
s_ptr[tid] += s_ptr[tid + 1];
}
if (tid == 0) {
g_odata[blockIdx.x] = s_data[0];
}
}
main{
...
dim3 dimBlock(128);
dim3 dimGrid(N/dimBlock.x);
sum_reduction<<<dimGrid, dimBlock>>>(in, out, N);
...
}
答案 0 :(得分:4)
像这样调用内核可以解决问题。
dim3 dimBlock(128);
dim3 dimGrid(N/dimBlock.x);
int smemSize = dimBlock.x * sizeof(int);
sum_reduction<<<dimGrid, dimBlock, smemSize>>>(in, out, N);
答案 1 :(得分:-3)
好的,我想你需要重新开始。请参阅reduction
上的NVIDiA分步流程指南