Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何自动确定二维阵列的CUDA块大小和网格大小?_C++_Image Processing_Cuda - Fatal编程技术网

C++ 如何自动确定二维阵列的CUDA块大小和网格大小?

C++ 如何自动确定二维阵列的CUDA块大小和网格大小?,c++,image-processing,cuda,C++,Image Processing,Cuda,如何在CUDA中自动确定2D阵列(如图像处理)的块大小和网格大小 CUDA有CUDAOccupancyMappotentialBlockSize()函数自动计算CUDA内核函数的块大小。看见在这种情况下,它适用于一维阵列 对于我的情况,我有一个640x480图像 如何确定块/网格大小? 我使用: 如果我设置x_block_size=32;y_block_size=32手动运行,无错误 我可以问一下为什么CUDA会收到无效的配置参数错误消息吗?似乎我不能直接为2D数组使用cudaOccupancy

如何在CUDA中自动确定2D阵列(如图像处理)的块大小和网格大小

CUDA有
CUDAOccupancyMappotentialBlockSize()
函数自动计算CUDA内核函数的块大小。看见在这种情况下,它适用于一维阵列

对于我的情况,我有一个640x480图像

如何确定块/网格大小? 我使用:

如果我设置
x_block_size=32;y_block_size=32
手动运行,无错误

我可以问一下为什么CUDA会收到
无效的配置参数
错误消息吗?似乎我不能直接为2D数组使用
cudaOccupancyMapPotentialBlockSize()

潜在解决方案 我对潜在的解决方案有了一个想法:

如果我先计算线程数,然后使用
cudaoccuPancyMapPotentialBlockSize()
计算2D数组的块大小,会怎么样

////total_thread_num = 640x480 = 307200
int total_thread_num = image.width * image.height;

////compute block/grid size
int min_grid_size, grid_size, block_size;
cudaOccupancyMaxPotentialBlockSize
(
    &min_grid_size, &block_size,
    my_cuda_kernel,
    0, total_thread_num
);

grid_size = (total_thread_num + block_size - 1) / block_size;

//launch CUDA kernel function
my_cuda_kernel<<<grid_size, block_size>>>(<arguments...>);
问题2 如果问题1中的方法不可行,我可以使用上述方法吗

问题1我可以使用此方法计算块/网格大小吗

没有

重要的是要记住,这些API调用提供的是每个块的线程数,而不是块维度。如果在每个方向上运行两次API,那么当这两个值组合在一起时,可能会得到非法的块大小。例如,如果内核的占用率最大化线程数为256,那么您可能会得到256 x 256的块大小,这远远大于每个块的1024个线程总数,从而导致启动失败

问题2如果问题1中的方法不可行,我可以使用上述方法吗

原则上,这应该是可行的,尽管您会受到一点性能损失,因为整数模运算在GPU上不是特别快。或者,您可以从API返回的每个块的最大线程数计算满足您需要的2D块大小

例如,如果您只希望块维度中有32个线程的块,并且要映射到数据的主要顺序(用于内存合并),那么只需将线程数除以32(注意,API将始终返回每个块32个线程的整数倍,因为这是扭曲大小)。例如,如果API返回的每个块的线程数为384,那么块大小为32 x 12

如果你真的想要某种使用方形块的平铺方案,那么很容易计算出只有64(8 x 8)、256(16 x 16)、576(24 x 24)和1024(32 x 32)是可行的块大小,它们都是平方数和32的整数倍。在这种情况下,您可能希望选择小于或等于API返回的线程总数的较大块大小

最终,您如何选择这样做将取决于内核代码的要求。但是,设计一个与CUDA目前公开的块大小调整API兼容的2D块大小调整方案当然是可能的

CUDA Error! invalid configuration arguments
////total_thread_num = 640x480 = 307200
int total_thread_num = image.width * image.height;

////compute block/grid size
int min_grid_size, grid_size, block_size;
cudaOccupancyMaxPotentialBlockSize
(
    &min_grid_size, &block_size,
    my_cuda_kernel,
    0, total_thread_num
);

grid_size = (total_thread_num + block_size - 1) / block_size;

//launch CUDA kernel function
my_cuda_kernel<<<grid_size, block_size>>>(<arguments...>);
__global__ void my_cuda_kernel()
{
    //compute 2D index based on 1D index;
    unsigned int idx = BlockIdx.x * blockDim.x + threadIdx.x;
    unsigned int row_idx = idx / image.width;
    unsigned int col_idx = idx % image_width;

    /*kernel function code*/

}