How to optimize 2 identical kernels with 50% occupancy that could run concurrently in CUDA?
我在 CUDA 中有 2 个相同的内核,它们报告了 50% 的理论占用率并且可以同时运行。但是,在不同的流中调用它们会显示顺序执行。
每个内核调用的网格和块尺寸如下:
1 2 3 | Grid(3, 568, 620) Block(256, 1, 1 ) With 50 registers per thread. |
这会导致每个 SM 的线程过多,每个块的寄存器过多。
我应该把我的下一个优化工作集中在减少内核使用的寄存器数量上吗?
或者将网格拆分为许多较小的网格是否有意义,可能允许发布 2 个内核并同时运行。我每个块的寄存器数量仍然会在这里造成问题吗?
注意 - deviceQuery 报告:
1 2 3 | 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% 时耗尽了资源。如果您用尽了资源,则无法再运行任何 warp,无论是来自该内核还是其他任何内核。
However, calling them in different streams shows sequential execution.
由于上述原因,这正是应该预期的结果
Each kernel call has the grid and block dimensions as follows:
1 2 3 | 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?
鉴于并发内核执行的目标是不可能的,我认为目标应该是让这个内核尽可能快地运行。你如何做到这一点是特定于代码的。在某些情况下,寄存器优化可以提高占用率和性能,但有时所发生的只是溢出到本地内存,这会损害性能。
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.
当您说"很多"时,您将暗示数千个网格,这意味着启动和调度延迟如此之多,以至于我无法想象这样做有什么好处,如果您能够设法达到并发内核的地步执行是可能的。