Оптимизация времени компиляции с учетом постоянных аргументов функции - PullRequest
0 голосов
/ 29 июня 2018

У меня есть две функции void f(int x){...} и void g(int x){f(x);}. Я знаю, что 99% времени g() получает 3 или 5. В f(), x никогда не меняется и контролирует множество циклов и ветвей условий. Будет ли следующее быстрее, чем мой оригинальный код?

void g(int x)
{
  if(x == 3) f(3);
  else if(x == 5) f(5);
  else f(x);
}

Будет ли компилятор (g++ -Ofast) компилировать f(3) и f(5) отдельно от f(x), аналогично компиляции двух параметров шаблона? Что еще я должен сделать, чтобы компилятор мог легче распознать возможность оптимизации? Объявление void f(const int &x){...} полезно или необходимо?

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Если это критическая для производительности функция, и в 99% случаев вызывается f (3) или f (5), и вы пытаетесь оптимизировать, вы должны измерить разницу таких вызовов. Если f () является встроенной функцией, оптимизатор может работать с вашей константой лучше, чем с переменной, чтобы некоторые ее функции оценивались во время компиляции (например, постоянное свертывание, уменьшение прочности и т. Д.). Это может быть полезно Godbolt.org, чтобы посмотреть на сборку и посмотреть, есть ли очевидные улучшения. LTO также может помочь, даже если он не указан, хотя разные люди сообщают об этом на разных уровнях успеха.

Если вы не видите значительных улучшений, но думаете, что некоторые могут заранее знать x, вы можете также написать различные специализированные версии f (), такие как f3 () и f5 (), которые оптимизированы для этих случаев. (хотя вы могли бы также получить более крупную инструкцию и иметь проблемы с кэш-памятью. Все сводится к измерению того, что вы пытаетесь, и пониманию того, в чем заключаются преимущества (и потери). Самое важное - это измерить. Не так-то сложно сделать код сложным для нет выигрыша (или хуже, чтобы замедлить его во имя оптимизации.)

0 голосов
/ 29 июня 2018

Ответы на такие вопросы в конечном итоге вводят в заблуждение, поскольку они зависят не только от конкретной среды, которую вы используете, но и от другого кода, с которым ваш проект будет связывать, если будет использоваться оптимизация во время соединения. Кроме того, компилятор может генерировать несколько версий - несколько более «оптимальных», и тогда «оптимальность» зависит от того, кто вызывает g(). Если g() является constexpr - сделайте это так, компилятор может использовать этот факт для оптимизации.

В любом случае: вам нужно посмотреть на вывод вашего компилятора; с кодом, как он скомпилирован в ваш проект. Только тогда ты сможешь сказать. В качестве прелюдии вам следует обратиться в Compiler Explorer по адресу https://godbolt.org и убедиться в изолированной среде.

...