cuda中虚拟方法的缺点

eap*_*nte 5 c++ cuda virtual-functions nvcc

据我了解,虚拟方法调用是后期绑定,因此无法由编译器内联。显然,nvcc 严重依赖内联代码。我想知道如果在 Cuda 的内核中使用虚拟方法是否有任何严重的缺点。有哪些情况应该避免?它们会对性能产生影响吗?

use*_*016 5

如果编译器可以对调用进行去虚拟化,它就可以将其转换为常规方法调用,甚至内联它。为 NVCC 提供支持的 Clang/LLVM 在某些情况下能够做到这一点,作为一种优化。您必须检查生成的代码才能知道是否是这种情况。

如果编译器无法对调用进行去虚拟化,则可能会对性能产生影响,特别是当该调用位于热路径上时。虚拟呼叫需要:

  1. vtable 查找;
  2. 间接分支。

vtable 查找需要内存访问,速度很慢(并且可能“浪费”可以更好地使用的缓存线),并且间接分支通常很昂贵。此外,如果 warp 中并非所有线程都将虚拟方法解析为同一地址(例如,在处理具有不同具体类型的对象数组时),这将导致 warp 发散,这是另一个性能损失。

话虽这么说,如果您不在热路径上调用虚拟方法,则影响应该可以忽略不计。如果没有进一步的代码,就无法判断。

  • @eaponte Direct分支将目标地址直接存储在指令中,因此很容易继续获取分支的目标,它可以在获取指令时查看指令并获取目标地址。间接分支必须从内存中获取值才能找到其目标地址,因此指令获取阶段将不知道从哪里继续,直到潜在的长内存访问完成为止。 (2认同)