Во многих дискуссиях о ключевом слове inline
в объявлениях функций кто-то укажет, что в некоторых случаях он может сделать вашу программу медленнее - в основном из-за взрыва кода, если я прав. Я никогда не встречал такого примера на практике сам. Каков фактический код, в котором можно ожидать, что использование inline
может нанести ущерб производительности?
Есть ли реальный пример, когда inline вредит производительности программы на C?
Ответ 1
Ровно 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. Делает ядро меньше и быстрее. deraadt @ok
Насколько я помню, двоичное сокращение ядра сократилось более чем на 100 кбайт, а не один тестовый пример, который стал медленнее, и несколько макро-тестов (например, компиляция ядра) были значительно быстрее (5-10%, если я правильно помню, но не цитируйте меня на этом).
Примерно в то же время я отправился на поиски, чтобы фактически измерить встроенные функции в ядре OpenBSD. Я нашел несколько, которые имели минимальный прирост производительности, но большинство из них оказывало 0 измеримое воздействие, а несколько человек делали вещи намного медленнее и были убиты. По крайней мере еще одно uninlining оказало огромное влияние, и это был внутренний макрос malloc (где идея заключалась в inline malloc, если он имел размер, известный во время компиляции) и распределители пакетов пакетов, которые сократили ядро на 150 КБ и имели значительную производительность улучшение.
Можно предположить, хотя у меня нет доказательств, что это связано с тем, что ядро большое, и мы изо всех сил стараемся оставаться внутри кеша при выполнении системных вызовов, и каждый бит помогает. Итак, что фактически помогло в этих случаях, было просто сокращение двоичного кода, а не количество выполненных инструкций.
Ответ 2
Представьте себе функцию, у которой нет параметров, но интенсивное вычисление с постоянным количеством промежуточных значений или использованием регистров. Затем Inline это функция в коде, имеющем согласованное количество промежуточных значений или использование регистров.
Отсутствие параметров делает процедуру вызова более легкой, потому что не требуются операции стека, требующие много времени.
Когда встроенный компилятор должен сохранять много регистров и разливать другие, которые будут использоваться с новой функцией, воспроизводить процесс регистров и резервное копирование данных, необходимых для вызова функции, возможно, наихудшим образом.
Если операции резервного копирования более экспансивны, с точки зрения времени и машинных циклов, по сравнению с механизмом вызова функции, особенно если функция широко называется, то у вас есть вредный эффект.
Это, по-видимому, относится к некоторым конкретным функциям, которые в основном используются в ОС.