我写了一个有几个子程序的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的程序代码仍然适合流式多处理器的指令缓存,而其他版本太大。这可能会导致全局内存访问,从而可以加载更多的程序代码,延迟会导致这种差异。不幸的是,我找不到有关指令缓存大小的任何信息。
任何人都可以帮我解释这些结果吗?
答案 0 :(得分:0)
可能有几件事导致您的结果。有些可能包括:
缺乏A& B导致对剩余代码的一些额外优化。生成的代码可能不是更短,但可能仍然执行得更快。
优化器发现A中的某些代码也存在于B中(A和B可能仍然是独立的)。结果同时具有A& A; B比单独的A和单独的B减慢程序的速度。
在剩余代码中读取数据时,只有A或B(或两者都没有)会导致更好的内存访问模式或更多缓存命中。 (我说的是数据,而不是程序代码)
缺少A和B可能会导致更好的占用率,允许更多线程同时运行。
我非常怀疑指令缓存可能是个问题。即使全局内存读取是必要的,它也永远不会“错位”,因为warp总是只需要一条指令。我的猜测是他们使用一些专用硬件作为指令。