C++ 有没有办法直接在c+中访问RTTI+;改进虚拟呼叫中的分支预测?
所以我正在创建一个库,它将有一个类someBase{};它将由多个类中的下游用户派生C++ 有没有办法直接在c+中访问RTTI+;改进虚拟呼叫中的分支预测?,c++,rtti,virtual-functions,branch-prediction,C++,Rtti,Virtual Functions,Branch Prediction,所以我正在创建一个库,它将有一个类someBase{};它将由多个类中的下游用户派生 class someBase { public: virtual void foo()=0; }; 我还有一个指向someBase的指针向量,我正在这样做:- vector <someBase*> children; // downstream user code populates children with some objects over here for (i=0; i&
class someBase {
public:
virtual void foo()=0;
};
我还有一个指向someBase的指针向量,我正在这样做:-
vector <someBase*> children;
// downstream user code populates children with some objects over here
for (i=0; i<children.size(); i++)
children[i]->foo();
向量子;
//下游用户代码在这里用一些对象填充子对象
对于(i=0;ifoo();
现在,分析表明,虚拟调用上的分支预测失误是我代码中的(几个)瓶颈之一。我想做的是以某种方式访问对象的RTTI,并使用它根据类类型对子向量进行排序,以改进指令缓存局部性和分支预测
关于如何做到这一点,有何建议/解决方案
需要牢记的主要挑战有:
1.)我真的不知道将从someBase派生哪些类或多少类。假设,我可以在某个公共文件中的某个地方有一个全局枚举,下游用户可以编辑它来添加自己的类类型,然后根据它进行排序(基本上实现我自己的RTTI)。但这是一个丑陋的解决方案
2.)PiotrNycz在下面的回答中建议使用type_信息。但是,只有!=和==是为此定义的。关于如何在type_info上导出严格弱序有什么想法吗
3.)我确实希望改进分支预测和指令缓存位置,因此,如果有替代解决方案,也会受到欢迎 有
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);
}
[更新]
谢谢你告诉我,有一个函数是为这个目标设计的。它是std::type_info::before(const type_info&)const
,因此比较器将非常简单:
inline bool compareTypes(A* obj1, A* obj2)
{
return typeid(*obj1).before(typeid(*obj2));
}
我以前的版本还不错;)它可用于还需要对给定类的对象进行排序的情况。您可以在初始化时按类型对指针进行一次分类,例如:
std::vector<derivedA*> derivedA_list;
std::vector<derivedB*> derivedB_list;
//...
for (i=0; i<children.size(); i++)
if (derivedA *d = dynamic_cast<derivedA*>(children[i]))
derivedA_list.push_back(d);
else if (derivedB *d = dynamic_cast<derivedB*>(children[i]))
derivedB_list.push_back(d);
//...
std::向量派生数据列表;
std::矢量衍生的B_列表;
//...
对于(i=0;i@EdS.我的错误。修复了问题中的问题。是的,但是您只有!=和==为type_info定义。关于如何从中派生严格弱排序,有什么想法吗?您有从typeid返回的typeinfo返回的名称字符串。啊…有意义…非常感谢!我只是做了一些更新。我不确定type_info
接口。type_info::name()
returnconst char*
可以使用非常简单的strcmp
。不确定()
-可能应该调用两次,以确定是否小于、等于或大于…@MooingDuck请参见问题。根据OP分析-分支预测是一个问题。因此OP希望对向量中的对象进行排序,以改进分支预测。我相信排序将执行一次,执行将多次。错误的转换,应该是动态播放
。
std::vector<derivedA*> derivedA_list;
std::vector<derivedB*> derivedB_list;
//...
for (i=0; i<children.size(); i++)
if (derivedA *d = dynamic_cast<derivedA*>(children[i]))
derivedA_list.push_back(d);
else if (derivedB *d = dynamic_cast<derivedB*>(children[i]))
derivedB_list.push_back(d);
//...
for (i=0; i<derivedA.size(); ++i)
derivedA_list[i]->derivedA::foo();
for (i=0; i<derivedB.size(); ++i)
derivedB_list[i]->derivedB::foo();