2012-09-19 64 views
4

所以我創建了一個類庫someBase {};這將由許多類別的下游用戶推導出來。有沒有辦法直接在C++中訪問RTTI來改進虛擬調用中的分支預測?

class someBase { 
    public: 
    virtual void foo()=0; 
}; 

什麼我也有,是指針的向量some​​Base,我這樣做: -

vector <someBase*> children; 

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

for (i=0; i<children.size(); i++) 
    children[i]->foo(); 

現在分析表明,虛擬呼叫的分支預測失誤,是一個(的幾個)我的代碼中的瓶頸。我想要做的是以某種方式訪問​​對象的RTTI,並使用它來根據類類型對子向量進行排序,以改進指令緩存局部性和分支預測。

任何關於如何做到這一點的建議/解決方案?

要記住的主要挑戰是: -

1)我真的不知道哪個或多少類是打算從someBase的。假設我可以在某個公共文件中有一個全局枚舉,讓下游用戶可以編輯它們以添加他們自己的類類型,然後對其進行排序(基本實現自己的RTTI)。但這是一個醜陋的解決方案。

2.)PiotrNycz在他的回答中建議使用type_info。但是,只有!=和==是爲此定義的。關於如何在type_info上導出嚴格的弱排序的任何想法?

3.)我真的希望改善分支預測和指令緩存局部性,所以如果有替代解決方案,那也是值得歡迎的。

+0

@EdS。我的錯。修正了這個問題。 – owagh

回答

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); 
} 

和:

sort(v.begin(), v.end(), compareTypes); 

[更新]

感謝poiting我出去,有專爲這一目標的功能。這是std::type_info::before(const type_info&) const所以比較會因爲這很容易:

inline bool compareTypes(A* obj1, A* obj2) 
{ 
    return typeid(*obj1).before(typeid(*obj2)); 
} 

我的早期版本並沒有那麼糟糕;)它可以用來情況下一個需要還排序定類的對象。

+0

是的,但你只有!=和==爲type_info定義。任何關於如何從中得出一個嚴格的弱秩序的想法? – owagh

+0

您有從typeid返回的typeinfo返回字符串的名稱。 – PiotrNycz

+0

ahhh ...有道理...非常感謝! – owagh

0

您可以通過類型指針進行分類,一旦在初始化時,通過使用例如:

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(); 

還要注意使用迭代器的循環可能會更好地優化。

+1

錯誤的轉換,應該是'dynamic_cast'。 – MSalters

相關問題