如何在 CUDA 中同时优化 2 个占用率为 50% 的相同内核 运行?

How to optimize 2 identical kernels with 50% occupancy that could run concurrently in CUDA?

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

每个内核调用的网格和块维度如下:

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

这会导致每个 SM 的线程过多,每个块的寄存器过多。

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

或者将网格拆分为许多更小的网格是否有意义,可能允许发布 2 个内核并同时 运行。我这里每个块的寄存器数量是否仍然存在问题?

注意 - 设备查询报告:

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 个块的内核。这比最大的 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?

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

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.

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