【发布时间】:2012-11-23 06:09:23
【问题描述】:
我编写了一个包含多个子例程的 CUDA 程序。当我禁用子例程 A 时,运行时间会提高 a 量。当我禁用子例程 B 时,运行时间会提高 b 量。当我禁用子例程 A 和 B 时,运行时间会提高 c > a + b。两个子程序完全相互独立。
下一部分可能是一种幼稚的分析方法,但这是我所做的:我编译了每个版本的代码并为每个二进制文件运行 cuobjdump --dump-sass。结果输出是完整的二进制文件大约 1350 行,每个二进制文件大约 1100 行,其中一个子程序被禁用。如果我禁用这两个子程序,我会得到 850 行。看来我需要前三个每行 3.1 us 和 2.4 us 来禁用两个子例程。
由于 A 和 B 不包含任何复杂的内容或比其他代码更密集地使用内存,我不认为这是由于注释掉所有时间密集型操作并让简单操作保持活动状态造成的。我的猜测是,禁用 A 和 B 的程序代码仍然适合流式多处理器的指令缓存,而其他版本太大。这可能会导致全局内存访问,以便可以加载更多程序代码,而延迟会导致这种差异。不幸的是,我找不到有关指令缓存大小的任何信息。
谁能帮我解释一下这些结果?
【问题讨论】:
-
您在进行此类分析时需要非常小心。 GPU 编译器和汇编器具有非常激进的“死代码删除”优化。如果编译器可以确定一个代码段对写入全局内存的结果没有贡献,它只会从内核中删除整个代码段。
-
是的,但这不应该在我运行 cuobjdump --dump-sass 时已经发生吗?我想知道运行时间的下降以及这是否与二进制代码的长度有关。
-
当前版本的 CUDA 分析器不显示指令缓存统计信息。 Nsight Visual Studio Edition CUDA Profiler 确实显示了停顿的原因。如果主要的停顿原因是 Fetch,那么内核可能会破坏 icache,或者您有很多跳转。进一步的解释需要分析报告和代码审查。
-
您检查过寄存器使用情况吗?可能是 A 或 B 需要的寄存器比 A 或 B 都多。减少的寄存器数量可能会提高占用率,从而提高性能。
-
每个流式多处理器的块数受共享内存使用限制为 8 个,并且每个块使用的寄存器少于 40 个。所以那里的入住率没有增加。
标签: performance cuda