Скорость лямбда против включения функции

У меня проблемы со скоростью с лямбда-функциями. Вот код:

Lit Simplifier::lit_diff_watches(const OccurClause& a, const OccurClause& b)
{
set_seen_for_lits(b, 1);

size_t num = 0;
Lit toret = lit_Undef;
const auto check_seen = [&] (const Lit lit) {
if (seen[lit.toInt()] == 0) {
toret = lit;
num++;
}
};
for_each_lit(a, check_seen);
/*switch(a.ws.getType()) {
case CMSat::watch_binary_t:
check_seen(a.lit);
check_seen(a.ws.lit2());
break;

case CMSat::watch_tertiary_t:
check_seen(a.lit);
check_seen(a.ws.lit2());
check_seen(a.ws.lit3());
break;

case CMSat::watch_clause_t: {
const Clause& clause = *solver->clAllocator->getPointer(a.ws.getOffset());
for(const Lit lit: clause) {
check_seen(lit);
}
break;
}
}*/
set_seen_for_lits(b, 0);

if (num == 1)
return toret;
else
return lit_Undef;
}

for_each_lit подпись функции:

void for_each_lit(
const OccurClause& cl
, std::function<void (const Lit lit)> func
);

Функция lit_diff_watches работает миллионы раз, и это займет 3,3 с на примере. Однако, когда я раскомментирую переключатель и закомментирую for_each_line (это копия-вставка переключателя), я получаю 1.7s для того же точного запуска. Обратите внимание, что в 99% случаев watch_binary_t или же watch_tertiary_t случается, то есть только очень немногие инструкции должны быть выполнены за lit_diff_watches вызов функции.

Подскажите, пожалуйста, что я делаю не так? Поведение одинаково как для GCC 4.7, так и для текущей версии llvm-svn (25 ноября 2013 г.), временные различия незначительны. Я предполагаю, что вызов функции не встроен, но я не эксперт. Я хотел бы исправить это, потому что это switch(..){..} находится во многих-многих местах в коде, и использование лямбд & for_each_lit значительно очистит код Однако я не могу потерять так много скорости из-за этого. 10-20% было бы хорошо, но замедление почти в 2 раза — это слишком много.

0

Решение

cbreak-работа помогла мне на IRC-канале # c ++ freenode. Он предложил то, что «Керрек С.Б.» написал выше в комментариях. Я изменился for_each_litобъявление к:

template<class Function>
void for_each_lit(
const OccurClause& cl
,  Function func
);

и скорость теперь одинакова для обеих реализаций. По-видимому, компилятор не смог выполнить оптимизацию во время компоновки, чтобы убрать вызов виртуальной функции, поэтому накладные расходы были огромными.

Спасибо всем за помощь всем!

1

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

Других решений пока нет …

По вопросам рекламы [email protected]