Есть ли способ получить прямой доступ к RTTI в c ++ для улучшения предсказания ветвлений в виртуальных вызовах?

Поэтому я создаю библиотеку, которая будет иметь класс 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<children.size(); i++)
children[i]->foo();

Теперь профилирование позволяет предположить, что ошибочные прогнозы ветвления для виртуальных вызовов являются одним (из нескольких) узких мест в моем коде. То, что я хочу сделать, так или иначе получить доступ к RTTI объектов и использовать его для сортировки вектора детей по типу класса, чтобы улучшить как локальность кэша инструкций, так и предсказание ветвлений.

Любые предложения / решения о том, как это можно сделать?

Основные проблемы, которые следует иметь в виду:

1.) Я действительно не знаю, какие или сколько классов будут получены из someBase. Гипотетически, я мог бы иметь глобальное перечисление в каком-то обычном файле, который нижестоящие пользователи могут редактировать, чтобы добавить свой собственный тип класса, а затем отсортировать по нему (в основном реализуя мой собственный RTTI). Но это уродливое решение.

2.) PiotrNycz предлагает в своем ответе ниже использовать type_info. Тем не менее, только! = И == определены для этого. Любые идеи о том, как получить строгий слабый порядок на type_info?

3.) Я действительно хочу улучшить предсказание ветвлений и локальность кэша инструкций, поэтому, если есть альтернативное решение, это также будет приветствоваться

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

А также:

  sort(v.begin(), v.end(), compareTypes);
[ОБНОВИТЬ]

Спасибо, что предупредили меня, что есть функция, предназначенная для этой цели. это std::type_info::before(const type_info&) const Так что компаратор будет таким же простым, как этот:

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

Моя ранняя версия не так уж плоха;) Она может быть использована для случаев, когда нужно отсортировать также объекты данного класса.

3

Другие решения

Вы можете классифицировать указатели по типу один раз в инициализации, используя, например:

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

Также обратите внимание, что циклы с использованием итераторов, вероятно, будут лучше оптимизированы.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector