[C++] Какова стоимость вызова функции?



Answers

Вызов функции - это просто сдвиг указателя кадра в памяти на стек и добавление к нему нового кадра. Параметры функции смещаются в локальные регистры для использования, и указатель стека продвигается к новой вершине стека для выполнения функции.

По сравнению со временем

Функция вызова ~ простой доступ к памяти
Вызов функции <Disk Access
Вызов функции <доступ к памяти на другом компьютере
Вызов функции <доступ к диску на другом компьютере

Question

В сравнении с

  • Простой доступ к памяти
  • Доступ к диску
  • Доступ к памяти на другом компьютере (в той же сети)
  • Доступ к диску на другом компьютере (в той же сети)

в C ++ на окнах.




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

Во всем остальном вызов функции - это много (много) величин быстрее.




Стоимость фактического вызова функции, но не полного ее выполнения? или стоимость фактического выполнения функции? просто настройка вызова функции - это не дорогостоящая операция (обновление ПК?). но, очевидно, стоимость выполнения функции полностью зависит от того, что делает функция.




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

Итак .. говоря относительно:

  • Вызов функции> Простой доступ к памяти.
  • Вызов функции << Доступ к диску - по сравнению с памятью он может быть в сотни раз дороже.
  • Вызов функции << Доступ к памяти на другом компьютере - пропускная способность сети и протокол - великие убийцы времени здесь.
  • Вызов функции <<< Доступ к диску на другом компьютере - все вышеперечисленное и многое другое :)



Если функция встроена во время компиляции, стоимость функции становится равной 0.

0, конечно, то, что вы получили бы, не имея вызова функции, т. Е. Вложили его сами.

Это, конечно, звучит чрезмерно очевидно, когда я пишу это так.




В зависимости от того, что делает эта функция, она будет падать 2-м в вашем списке, если бы она выполняла логику с объектами в памяти. Далее вниз список, если он включает в себя доступ к диску / сети.




Предполагая, что вы имеете в виду накладные расходы самого вызова, а не то, что может сделать вызываемый, это определенно далеко, намного быстрее, чем все, кроме «простого» доступа к памяти.

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

Также обратите внимание, что «простой» доступ к памяти иногда не является - если ОС должна принести страницу с диска, тогда у вас есть длинное ожидание на ваших руках. То же самое было бы верно, если вы перейдете в код, который в настоящее время выгружается на диск.

Если основной вопрос: «Когда мне следует оптимизировать мой код, чтобы свести к минимуму общее количество вызовов функций?», Тогда ответ «очень близок к никогда».




Links