Если мы игнорируем SMT (f.ex. гиперпоточность), то большинство архитектур имеют предиктор ветвления для каждого аппаратного потока. Плотно соединен с блоком извлечения отдельного сердечника. Несколько (AMD?) Хранят информацию о прогнозировании ветвлений в I-кеше L1/L2, но в основном нацелены на следующую выборку.
Итак, если вы не запустите свой код на SMT, вы находитесь на небесах и получите 100% предсказание каждый раз за счет нескольких инструкций.
Если вы запустите свой код на SMT, вы часто обнаружите, что ваша жизнь - это ад, с 50 +% неправильным прогнозом.
Теперь вы можете решить вашу проблему легко, просто вам нужно использовать больше кода, проверить свое состояние раньше и называть ветку своего кода с помощью do_something или do_else.
Если у вас есть цикл, который вызывает вашу функцию, где у вас есть свой филиал вы можете сделать что-то вроде:
если (что-то) do_something_loop(); еще do_else_loop();
void do_something_loop() { для (авто x: myVec) do_something; }
Это имеет тот недостаток, что вам необходимо поддерживать 2 почти равных ветви кода.
Или вы можете иметь свою ветку в вызове функции branch_me(), который вы можете создать функцию шаблона, и из-за магии удаления мертвого кода вы не должны получать никаких ветвей в циклах.
C++ Концептуальный код.
template<bool b_something>
void brancher() {
// do things
if (b_something)
// do_something
else
// do_else
}
// do more things
}
void branch_user() {
if (something) {
for (auto x : myVec)
brancher<true>();
} else {
for (auto x : myVec)
brancher<false>();
}
}
Теперь вам нужно поддерживать только две ветви внешней функции, которые, надеюсь, меньше работают.
Определить нить. CPU, очевидно, не знает о потоках ОС. Но большинство процессоров в эти дни знают об аппаратных потоках. –
Прогнозирование филиала - это деталь реализации процессора, которая работает с разрешением наносекунды. Исполнение потока выполняется с разрешением в миллисекундах. Эти разницы в 6 порядков делают проблему нерелевантной. –