optimization - 如何优化2个相同的内核,占用率50%,可以在CUDA中同时运行?

标签 optimization cuda hpc

我在 CUDA 中有 2 个相同的内核,报告理论占用率为 50%,并且可以同时运行。但是,在不同的流中调用它们会显示顺序执行。

每个内核调用都有如下的网格和 block 尺寸:

Grid(3, 568, 620)
Block(256, 1, 1 )
With 50 registers per thread.

这会导致每个 SM 的线程过多以及每个 block 的寄存器过多。

我下一步的优化工作应该集中在减少内核使用的寄存器数量上吗?

或者将网格分割成许多较小的网格是否有意义,从而可能允许发布两个内核并同时运行。每个 block 的寄存器数量还会造成问题吗?

注意 - deviceQuery 报告:

MAX_REGISTERS_PER_BLOCK 65K
MAX_THREADS_PER_MULTIPROCESSOR 1024
NUMBER_OF_MULTIPROCESSORS 68

最佳答案

I have 2 identical kernels in CUDA that report 50% theoretical occupancy ...

确定

... and could be run concurrently

这不是占用率的含义,也是不正确的。

50% 的占用率并不意味着您有 50% 的未使用资源可供不同的内核同时使用。这意味着当运行最大理论并发扭曲数的 50% 时,您的代码耗尽了资源。如果您耗尽了资源,则无法再运行任何扭曲,无论它们来自该内核还是任何其他内核。

However, calling them in different streams shows sequential execution.

由于上述原因,这正是应该预期的

Each kernel call has the grid and block dimensions as follows:

Grid(3, 568, 620)
Block(256, 1, 1 )
With 50 registers per thread.

您提供了一个可启动 1041600 个 block 的内核。这比最大的 GPU 可以同时运行的数量级还要高出几个数量级,这意味着如此巨大的网格的并发内核执行范围基本上为零。

This results in too many threads per SM and too many registers per block.

寄存器压力可能是限制占用率的原因

Should I focus my next efforts of optimization in reducing the number of registers used by the kernel?

鉴于并发内核执行的目标是不可能的,我认为目标应该是使该内核运行得尽可能快。如何做到这一点是特定于代码的。在某些情况下,寄存器优化可以提高占用率和性能,但有时发生的只是溢出到本地内存,从而损害性能。

Or does it make sense to split the grid in many smaller grids, potentially allowing for the 2 kernels to be issued and to run concurrently.

当你说“很多”时,你会暗示数千个网格,这意味着如此多的启动和调度延迟,如果你能设法达到并发内核的程度,我无法想象这样做有什么好处执行是可能的。

关于optimization - 如何优化2个相同的内核,占用率50%,可以在CUDA中同时运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62882775/

相关文章:

cuda - Thrust:如何返回事件数组元素的索引

c++ - 并行转置不同的矩阵

mpi - 我们可以在单个系统中运行 MPI 程序还是必须仅在集群中运行它?

java - 无法运行 COMPS 应用程序。 ClassNotFoundException异常

c - 防止在初始化之前使用函数,类似于 C 中的构造函数

java - java是否进行内部优化?

linux - make-kpkg 使用 -O0 为 kgdb 构建内核

windows - 使用 LLVM/Clang 在 Win10 上使用 OpenMP 的 Cuda

bash - 在 slurm 处理的 bash 脚本中评论

c++ - 当数组内容改变时更新指向数组元素的指针