Подтвердить что ты не робот

Могу ли я выборочно (принудительно) встроить функцию?

В книге Чистый код (и еще несколько других, с которыми я столкнулся и прочитал) предлагается сохранить функции маленькими и разбить их, если они станут большой. Это также предполагает, что функции должны делать только одно и только одно.

В Оптимизация программного обеспечения на С++ Agner Fog заявляет, что ему не нравится правило разбивать функцию только потому, что она пересекает определенный порог ряда строк. Он утверждает, что это приводит к ненужным переходам, которые ухудшают производительность.

Во-первых, я понимаю, что не будет иметь значения, не работает ли код, над которым я работаю, в сложном цикле и что функции тяжелы, так что время, которое требуется для их вызова, затмевается ко времени, когда код в функция выполняет. Но предположим, что я работаю с функциями, которые в большинстве случаев используются другими объектами/функциями и выполняют относительно тривиальные задачи. Эти функции следуют рекомендациям, перечисленным в первом абзаце (т.е. Выполняют одну единственную функцию и малы/понятны). Затем я начинаю программировать критическую для производительности функцию, которая использует эти другие функции в узком цикле и по существу является функцией кадра. Наконец, предположим, что встраивание их имеет преимущество для функции производительности, но не имеет никакой пользы для любой другой функции (да, я профилировал это, хотя и с большим количеством копирования и вставки, которое я хочу избежать).

Сразу же можно сказать, что тег функции inline и пусть компилятор выбирает. Но что, если я не хочу, чтобы все эти функции находились в файле .inl или отображались в заголовке? В моей текущей ситуации критически важные функции и другие функции, которые он использует, находятся в одном исходном файле.

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

4b9b3361

Ответ 1

Вы не можете заставить встроенный. Кроме того, вызовы функций довольно дешевы на современных процессорах по сравнению с затратами на проделанную работу. Если ваши функции достаточно велики, чтобы их нужно было разбить, дополнительное время, необходимое для выполнения вызова, будет практически ничем.

В противном случае вы можете... попробовать... использовать макрос.

Ответ 2

Ничего не мешает вам помещать встроенную в статическую функцию в файле .cpp.

Некоторые компиляторы имеют возможность принудительно выполнять встроенную функцию, см., например, атрибут GCC ((always_inline)) и тонна опций для точной настройки оптимизаций наложения (см. параметры -minline- *).

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

Ответ 3

Нет, inline - рекомендация для компилятора; это не заставляет его ничего делать. Кроме того, если вы работаете с MSVС++, обратите внимание, что __forceinline также является неправильным; это просто более сильная рекомендация, чем inline.

Ответ 4

Это как раз о хорошем старом стиле C, так как речь идет о С++. Я обдумывал это на днях, потому что во встроенном мире, где нужно быстро управлять скоростью и пространством, это может иметь значение (в отличие от всех слишком), не беспокойтесь об этом, ваш компилятор умный и память дешево распространена в разработке настольных компьютеров/серверов).

Возможное решение, которое я еще должен проверить, состоит в том, чтобы в основном использовать два имени для разных вариантов, что-то вроде

inline int _max(int a, int b) {
    return a > b ? a : b;
}

а затем

int max(int a, int b) {
    return _max(a, b);
}

Это даст возможность выборочно вызывать либо _max(), либо max() и при этом все еще иметь алгоритм, определенный один раз и только один раз.

Ответ 5

Компиляторы действительно действительно хороши в создании оптимизированного кода.

Я бы предложил просто организовать ваш код в логические группы (используя дополнительные функции, если это улучшенная читаемость), помечая их встроенными, если это необходимо, и позволить компилятору решить, какой код оптимально сгенерировать.

Ответ 6

Вставка - Например, если существует функция A, которая часто вызывает функцию B, а функция B относительно невелика, то оптимизация на основе профиля будет встроенной функцией B в функции A.

VS профилированные оптимизации

Вы можете использовать автоматическую оптимизацию профиля для Visual С++ в концентраторе производительности и диагностики для упрощения и оптимизации процесса оптимизации в Visual Studio или выполнить шаги по оптимизации вручную в Visual Studio или в командной строке, Мы рекомендуем подключаемый модуль, потому что его проще использовать. Информацию о том, как подключить плагин и использовать его для оптимизации вашего приложения, см. Профилированный оптимизированный плагин.