有没有办法直接在 C++ 中访问 RTTI 以改进虚拟调用中的分支预测?

owa*_*agh 5 c++ virtual-functions rtti branch-prediction

所以我正在创建一个库,它将有一个类 someBase {}; 这将由许多类的下游用户派生。

class someBase {
  public:
    virtual void foo()=0;
};
Run Code Online (Sandbox Code Playgroud)

我还有一个指向 someBase 的指针向量,我正在这样做:-

vector <someBase*> children;

// downstream user code populates children with some objects over here

for (i=0; i<children.size(); i++)
  children[i]->foo();
Run Code Online (Sandbox Code Playgroud)

现在分析表明,对虚拟调用的分支错误预测是我代码中的(几个)瓶颈之一。我想要做的是以某种方式访问​​对象的 RTTI 并使用它根据类类型对子项的向量进行排序,以改善指令缓存局部性和分支预测。

关于如何做到这一点的任何建议/解决方案?

要记住的主要挑战是:-

1.) 我真的不知道哪些或多少类将从 someBase 派生。假设,我可以在某个公共文件中的某个地方有一个全局枚举,下游用户可以编辑以添加他们自己的类类型,然后对其进行排序(基本上是实现我自己的 RTTI)。但这是一个丑陋的解决方案。

2.) PiotrNycz 在下面的回答中建议使用 type_info。但是,为此只定义了 != 和 ==。关于如何在 type_info 上导出严格弱排序的任何想法?

3.) 我真的很想改进分支预测和指令缓存局部性,所以如果有替代解决方案,那也将受到欢迎。

Pio*_*ycz 4

typeid运营商。

您可以使用它来定义比较器,以对向量中的对象进行排序。

像这样:

inline bool compareTypes(BaseClass* obj1, BaseClass* obj2)
{
   int compareRes = strcmp(typeid(*obj1).name(), typeid(*obj2).name());
   if (compareRes < 0) return true;
   if (compareRes > 0) return false;
   std::less<BaseClass*> ptrComp;
   return ptrComp(obj1, obj2); 
}
Run Code Online (Sandbox Code Playgroud)

和:

  sort(v.begin(), v.end(), compareTypes);
Run Code Online (Sandbox Code Playgroud)

[更新]

感谢您向我指出有一个为此目标而设计的功能。所以std::type_info::before(const type_info&) const比较器将像这样简单:

inline bool compareTypes(A* obj1, A* obj2)
{
   return typeid(*obj1).before(typeid(*obj2));
}
Run Code Online (Sandbox Code Playgroud)

我的早期版本还不错;)它可以用于需要对给定类的对象进行排序的情况。