在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];
}
}
Run Code Online (Sandbox Code Playgroud)
我很好奇的是blocksPerGrid的初始化.我不明白为什么会这样
int blocksPerGrid = (numElements + threadsPerBlock - 1) / threadsPerBlock;
Run Code Online (Sandbox Code Playgroud)
而不是直截了当
int blocksPerGrid = numElements / threadsPerblock;
Run Code Online (Sandbox Code Playgroud)
这似乎是一种很常见的习惯.我在各种项目中看到过.他们都是这样做的.我是cuda的新手.欢迎任何解释或背后的知识.
计算的方式是你看到允许numElements
不是圆的倍数的情况threadsPerblock
.
例如,使用threadsPerblock = 256
和numElements = 500
(numElements + threadsPerBlock - 1) / threadsPerBlock = (500 + 255) / 256 = 2
Run Code Online (Sandbox Code Playgroud)
而
numElements / threadsPerblock = 500 / 256 = 1
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,运行512个线程,覆盖输入数据中的500个元素,但在第二种情况下,仅运行256个线程,留下244个未处理的输入项.
还要注意内核中的这种"保护"代码:
int i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < numElements)
{
... Access input here
}
Run Code Online (Sandbox Code Playgroud)
对于防止任何额外线程执行越界内存操作至关重要.
归档时间: |
|
查看次数: |
122 次 |
最近记录: |