cuda - cuda中每个网格分配习惯的 block

标签 cuda gpgpu nvidia

在分配网格大小时,我在 cuda 示例中看到了一个常见的习惯。下面是一个例子:

int 
main(){

    ...
    int numElements = 50000;
    int threadsPerBlock = 1024;
    int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;

    vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, numElements);
    ...
}

__global__ void
vectorAdd(const float *A, const float *B, float *C, int numElements)
{
    int i = blockDim.x * blockIdx.x + threadIdx.x;

    if (i < numElements)
    {
        C[i] = A[i] + B[i];
    }
}

我比较好奇的是blocksPerGrid的初始化。我不明白这是为什么

int blocksPerGrid = (numElements + threadsPerBlock - 1) / threadsPerBlock;

而不是直截了当

int blocksPerGrid = numElements / threadsPerblock;

这似乎是一个很普遍的习惯。我在各种项目中看到。他们都是这样做的。 我是cuda的新手。欢迎对此背后的任何解释或知识。

最佳答案

计算是按照您看到的方式完成的,以允许 numElements 不是 threadsPerblock 的整数倍的情况。

例如,使用 threadsPerblock = 256numElements = 500

(numElements + threadsPerBlock - 1) / threadsPerBlock = (500 + 255) / 256 = 2

鉴于

numElements / threadsPerblock = 500 / 256 = 1

在第一种情况下,运行了 512 个线程,覆盖了输入数据中的 500 个元素,但在第二种情况下,只运行了 256 个线程,留下 244 个输入项未处理。

还要注意内核中的这种“保护”代码:

int i = blockDim.x * blockIdx.x + threadIdx.x;

if (i < numElements)
{
    ... Access input here
}

对于防止任何额外线程执行越界内存操作至关重要。

关于cuda - cuda中每个网格分配习惯的 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17303249/

相关文章:

c - 如何使用编译器内部 __fmul_?

c++ - CUDA 动态并行,性能差

performance - CUDA 中的分歧 - 从内核中的线程退出

optimization - 有效地将无符号值除以 2 的幂,四舍五入 - 在 CUDA 中

cuda - 从命令提示符编译 CUDA 时出错

ubuntu - CUDA 中的矩阵行列式

double - 我应该如何在 OpenCL 中启用 cl_khr_fp64?

cuda - cuda 的 __shared__ 变量不允许初始化程序

c++ - CUDA 流破坏和 CudaDeviceReset