Комментарии 24
В C++20 атрибуты [[likely]]
и [[unlikely]]
— это часть языка. https://en.cppreference.com/w/cpp/language/attributes/likely
И как предсказатель узнает, что ему нужно что-то предсказывать, если он не знает, что перед ним команда ветвления? Адреса для перехода тоже ведь частью команды являются, разве нет?
Кстати, рекомендую поиграть в игры и туториалы, связанные с моделированием процессоров, такие, как MHRD, nand2teris, nandgame и подобные, чтобы понять, как работает декодер инструкций (по факту — самая менее затратная часть процессора по количеству элементов), и как группируются разнообразные инструкции в их битовом представлении.
С одной стороны да, производительность кода — это важно. С другой стороны, приведенные примеры вообще не показательны, поскольку состоят только из проблемного кода. Вот статья "ошибочно предсказанное ветвление снижает производительность Chrome в разы" была бы бомбой, особенно если бы была описана методика поиска таких "ошибочных" мест.
Кстати, perf тоже умеет показывать ошибочные предсказания.
Статанализ проверяет всевозможные ветви исполнения, независимо от их вероятности. Это основное преимущество стататализа.
Именно это и является его преимуществом над динамическими анализаторами, тем же valgrind-ом. Ему не нужно подсчитывать статистику посещения каждой ветви. Можно включать эвристику, наподобие такой: если в теле if нет исключений или abort или terminate, а в else — есть, то тело if более вероятное, чем else. Или если в switch инструкции разобраны все случаи перечисления, то ветка default, будет маловероятной и т.п. случаи.
Следует ожидать, что за каждую ошибку предсказания ветвления мы расплачиваемся более чем 10 циклами.
Мне кажется, автор имел в виду такты процессора.
Вот так правильней: godbolt.org/z/P6c-WP — и ветвление вернулось на место.
* Do not do this for predictable branches.
* Do not use these instructions to eliminate all unpredictable conditional branches (because using these instructions will incur execution overhead due to the requirement for executing both paths of a conditional branch).
* In addition, converting a conditional branch to SETCC or CMOV trades off control flow dependence for data dependence and restricts the capability of the out-of-order engine.
* When tuning, note that all Intel 64 and IA-32 processors usually have very high branch prediction rates. Consistently mispredicted branches are generally rare. Use these instructions only if the increase in computation time is less than the expected cost of a mispredicted branch.
И почему отказались от delayed branch (был, например, в hitachi sh3) в пользу branch prediction?
Ошибочно предсказанное ветвление может в разы увеличить время выполнения программы