Однострочное изменение в GCC привело к ускорению на 12% в одном тесте и замедлению на 14% в другом

Инженер из компании Intel внёс в набор компиляторов GCC однострочное изменение, увеличивающее вес неверного предсказания ветвления на процессорах x86. Изменение позволило повысить производительность генерируемого кода при прохождении теста 544.nab_r на 12.7% при включении в оптимизаций «-O2 -mtune=graniterapids» для CPU Intel Granite Rapids/Xeon 6 и на 12.1% при включении в оптимизаций «-O2 -mtune=znver5» на CPU AMD Zen5.

Изменение веса с «COSTS_N_INSNS (2)» до «COSTS_N_INSNS (2) + 3» увеличивает значимость ошибки предсказания c 2 до 5 условных инструкций, что лучше отражает особенности конвейеров обработки команд (pipeline) в современных CPU, в которых ошибки предсказания ветвления более затратны. Изменение веса приводит к форсированию преобразования компилятором выражений «if» в условные команды без переходов, такие как CMOV, исключающие приостановки при неверном предсказании ветвления, вызванные необходимостью сброса состояния конвейера. Ранее вес «COSTS_N_INSNS (2) + 3» указывался в GCC только для процессоров Intel Ice Lake и Alder Lake, а теперь выставлен для общего (generic) профиля процессоров x86.

Примечательно, что после принятия патча всплыла регрессия, из-за которой тест «Hint» стал выполняться у одного из разработчиков GCC на 30% медленнее при сборке с опциями «-march=generic -mtune=znver5» и «-march=generic -mtune=graniterapids». Производительность прохождения тестов SPEC2017 и SPEC2026 после внесения изменения осталась на прежнем уровне. Наличие регрессии подтверждено автором изначального коммита, по его данным замедление прохождения теста Hint составляет 14% при сборке с опциями «-O2 -mtune=generic -march=x86-64-v3».

Замедление объясняется тем, что в коде теста Hint имеется только одна условная конструкция, преобразуемая GCC в представление на базе CMOV. Данная конструкция выполняется достаточно редко (в 3%) и её оптимизация не влияет на производительность. При этом изменение режима генерации кода привело к побочному эффекту, замедлившему выполнение более часто выполняемого кода.

Источник: http://www.opennet.ru/opennews/art.shtml?num=65757