<p>要调整内核的执行参数大小,您需要做两件事(按此顺序):</p>
<h2>一。确定块大小</h2>
<p>块大小主要由硬件限制和性能决定。我建议您阅读<a href="https://stackoverflow.com/q/9985912/681865">this answer</a>以获得更详细的信息,但简短的总结是,您的GPU对它可以运行的每个块的线程总数有一个限制,并且它有一个有限的寄存器文件、共享内存和本地内存大小。您选择的块维度必须在这些限制内,否则内核将不会运行。块大小也会影响内核的性能,您会发现块大小可以提供最佳性能。块大小应该始终是warp大小的整数倍,到目前为止,所有CUDA兼容硬件上的warp大小都是32。</p>
<h2>2。确定网格大小</h2>
<p>对于您所展示的内核类型,您需要的块的数量与输入数据的数量和每个块的大小直接相关。</p>
<p>例如,如果输入数组大小为943x1682,并且块大小为16x16,则需要59 x 106网格,这将在内核启动时产生944x1696个线程。在这种情况下,输入数据大小不是块大小的整数倍,您需要修改内核以确保它不会读取越界。一种方法可能是:</p>
<pre><code>__global__ void euclidean(float *x, float *y, float *solution) {
int idx = threadIdx.x + blockDim.x * blockIdx.x;
int idy = threadIdx.y + blockDim.y * blockIdx.y;
if ( ( idx < %(NCOLS)s ) && ( idy < %(NDIM)s ) ) {
.....
}
}
</code></pre>
<p>启动内核的python代码可能类似于:</p>
<pre><code>bdim = (16, 16, 1)
dx, mx = divmod(cols, bdim[0])
dy, my = divmod(rows, bdim[1])
gdim = ( (dx + (mx>0)) * bdim[0], (dy + (my>0)) * bdim[1]) )
func(drv.In(X), drv.In(Y), drv.Out(solution), block=bdim, grid=gdim)
</code></pre>
<p><a href="https://stackoverflow.com/q/5643178/681865">This question and answer</a>也可能有助于理解这个过程是如何工作的。</p>
<p>请注意,以上所有代码都是在浏览器中编写的,从未经过测试。使用它的风险由你自己承担。</p>
<p>还要注意的是,它是基于对代码的非常简短的阅读,可能是不正确的,因为您还没有真正描述在您的问题中如何调用代码。</p>