4

我编写了一个包含多个子程序的 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 的程序代码仍然适合流式多处理器的指令缓存,而其他版本太大。这可能会导致全局内存访问,以便可以加载更多程序代码,而延迟会导致这种差异。不幸的是,我找不到有关指令缓存大小的任何信息。

谁能帮我解释这些结果?

4

1 回答 1

0

可能有几件事会导致您的结果。有些可能包括:

  • 缺少 A & B 会导致对剩余代码进行一些额外的优化。生成的代码可能不会更短,但仍可能执行得更快。

  • 优化器发现 A 中的某些代码也存在于 B 中(A 和 B 可能仍然是独立的)。因此,同时拥有 A 和 B 比拥有单独的 A 和单独的 B 减慢程序的速度。

  • 在读取剩余代码中的数据时,只有 A 或 B(或两者都没有)会导致更好的内存访问模式或更多的缓存命中。(我说的是数据,不是程序代码)

  • 缺少 A 和 B 可能会导致更好的占用率,从而允许更多线程同时运行。

我非常怀疑指令缓存可能是问题所在。即使需要全局内存读取,它也永远不会“错位”,因为 warp 总是只需要一条指令。我的猜测是他们使用一些专用的硬件来执行指令。

于 2012-12-05T22:20:21.877 回答