Во многих дебатах о ключевом слове inline
в объявлениях функций кто-то укажет, что в некоторых случаях оно действительно может замедлить вашу программу — в основном из-за взрыва кода, если я не ошибаюсь. Сам такого примера на практике не встречал. Что такое фактический код, в котором использование inline
может отрицательно сказаться на производительности?
Есть ли реальный пример, когда встроенный код вреден для производительности программы на C?
Ответы (2)
Ровно 10 лет и один день назад я сделал этот коммит в OpenBSD:
http://www.openbsd.org/cgi-bin/cvsweb/src/sys/arch/amd64/include/intr.h.diff?r1=1.3;r2=1.4
Сообщение коммита было:
deinline splraise, spllower и setsoftint. Делает ядро меньше и быстрее. Дераадт @ хорошо
Насколько я помню, бинарный файл ядра уменьшился более чем на 100 КБ, и ни один тестовый пример не стал медленнее, а несколько тестов макросов (например, компиляция ядра) были заметно быстрее (на 5-10%, если я правильно помню, но не не цитируйте меня по этому поводу).
Примерно в то же время я отправился на поиски реального измерения встроенных функций в ядре OpenBSD. Я нашел несколько, которые имели минимальный прирост производительности, но большинство из них не оказали измеримого влияния, а некоторые сильно замедляли работу и были убиты. По крайней мере, еще одно отключение оказало огромное влияние, и это были внутренние макросы malloc (где идея заключалась в том, чтобы встроить malloc, если его размер был известен во время компиляции) и распределители буфера пакетов, которые уменьшили ядро на 150 КБ и имели значительную производительность. улучшение.
Можно предположить, хотя у меня нет доказательств, что это связано с тем, что ядро большое, и мы изо всех сил пытаемся оставаться внутри кеша при выполнении системных вызовов, и каждая мелочь помогает. Так что в этих случаях действительно помогало просто сокращение двоичного файла, а не количество выполняемых инструкций.
Представьте себе функцию без параметров, но с интенсивными вычислениями с постоянным количеством промежуточных значений или использованием регистров. Затем вставьте эту функцию в код, имеющий постоянное количество промежуточных значений или использование регистров.
Отсутствие параметров делает процедуру вызова более легкой, потому что не требуются операции со стеком, занимающие много времени.
При встраивании компилятор должен сохранить много регистров и пролить другие для использования с новой функцией, воспроизводя процесс регистров и резервного копирования данных, необходимых для вызова функции, возможно, в худшем случае.
Если операции резервного копирования более затратны с точки зрения времени и машинных циклов по сравнению с механизмом вызова функции, особенно если функция вызывается экстенсивно, то вы имеете пагубный эффект.
Похоже, это относится к некоторым конкретным функциям, широко используемым в ОС.
inline
— это всего лишь предложение; компилятор может игнорировать его. - person dan04   schedule 27.06.2014