我最近写了一个非常简单的内核:
__device__ uchar elem(const Matrix m, int row, int col) {
if(row == -1) {
row = 0;
} else if(row > m.rows-1) {
row = m.rows-1;
}
if(col == -1) {
col = 0;
} else if(col > m.cols-1) {
col = m.cols-1;
}
return *((uchar*)(m.data + row*m.step + col));
}
/**
* Each thread will calculate the value of one pixel of the image 'res'
*/
__global__ void resizeKernel(const Matrix img, Matrix res) {
int row = threadIdx.y + blockIdx.y * blockDim.y;
int col = threadIdx.x + blockIdx.x * blockDim.x;
if(row < res.rows && col < res.cols) {
uchar* e = res.data + row * res.step + col;
*e = (elem(img, 2*row, 2*col) >> 2) +
((elem(img, 2*row, 2*col-1) + elem(img, 2*row, 2*col+1)
+ elem(img, 2*row-1, 2*col) + elem(img, 2*row+1, 2*col)) >> 3) +
((elem(img, 2*row-1, 2*col-1) + elem(img, 2*row+1, 2*col+1)
+ elem(img, 2*row+1, 2*col-1) + elem(img, 2*row-1, 2*col+1)) >> 4);
}
}
它的基本功能是使用较大图像的值计算尺寸缩小图像的像素值。在resizeKernel中的'if'里面。
我的第一次测试没有正常工作。所以,为了找出发生了什么,我开始评论这笔钱的一些部分。一旦我减少了操作次数,就开始工作了。
我的理论是,它可能与可用内存有关,以存储表达式的中间结果。因此,减少每个块的线程数量,它开始完美运行,无需减少操作数量。
根据这些经验,我想知道如何更好地估计每个块的线程数,以避免内存需求优于我可用的内存。我怎么知道上面的操作需要多少内存? (当我们在它的时候,它是什么样的内存?缓存,共享内存等)。
谢谢!
答案 0 :(得分:2)
它主要是寄存器,你可以通过在编译内核的nvcc调用中添加-Xptxas="-v"
选项来找出每线程寄存器的消耗。汇编程序将返回每个线程的寄存器数,静态共享内存,本地内存和编译代码使用的常量内存。
NVIDIA制作占用率计算器电子表格(available here),您可以在其中插入汇编程序的输出,以查看块大小的可行范围及其对GPU占用率的影响。 CUDA编程指南的第3章还详细讨论了占用概念以及块大小和内核资源需求如何相互作用。