【问题标题】:Cons of virtual methods in cudacuda中虚拟方法的缺点
【发布时间】:2016-02-14 21:13:33
【问题描述】:

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

【问题讨论】:

  • 除非在编译时去虚拟化,否则它们会影响性能(它们需要 vtable 查找 + 间接分支)。如果 warp 中的线程不解析为相同的虚拟方法(例如,在处理具有不同具体类型的对象数组时),您将得到 warp 发散。尽可能避免它们。出于好奇,您正在编写什么样的应用程序,需要在 CUDA 代码中使用虚拟方法?
  • 不是 method 是“后期绑定”,而是方法 call 是后期绑定。有时。
  • 我正在开发一个 ODE 求解器。长话短说,我有一个名为 solve 的方法,它有两种不同的实现。我编写了一个带有纯虚函数的基类和两个覆盖此方法的子类。这是一个易于维护的解决方案,尽管它可能不是最佳的。尽管如此,我还是有兴趣了解有关此主题的更多信息。

标签: c++ cuda nvcc virtual-functions


【解决方案1】:

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

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

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

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

话虽如此,如果您不在热路径上调用虚拟方法,则影响应该可以忽略不计。没有更多的代码,这是不可能的。

【讨论】:

  • 我不熟悉间接分支的概念,你能解释一下这是什么吗?
  • @eaponte 直接分支将目标地址存储在指令中,因此很容易在分支目标处继续取指,它可以在取指时查看指令并获取目标地址。间接分支必须从内存中取出一个值来找到它们的目标地址,因此指令取出阶段在可能的长内存访问完成之前不知道从哪里继续。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 2015-06-13
  • 2013-05-01
  • 2016-06-30
  • 2011-09-30
  • 2015-09-09
相关资源
最近更新 更多