Fastcall действительно быстрее? - PullRequest
41 голосов
/ 03 февраля 2010

Действительно ли соглашение о вызовах fastcall действительно быстрее, чем другие соглашения о вызовах, такие как cdecl? Существуют ли какие-либо тесты, показывающие, как соглашение о вызовах влияет на производительность?

Ответы [ 4 ]

31 голосов
/ 03 февраля 2010

Это зависит от платформы.Например, для Xenon PowerPC это может быть разница на порядок из-за проблемы с загрузкой-попаданием в хранилище при передаче данных в стек.Я эмпирически рассчитал накладные расходы на функцию cdecl примерно на 45 тактов по сравнению с ~ 4 для fastcall.

Для вышедшего из строя x86 (Intel и AMD) влияние может быть значительнымменьше, потому что все регистры в любом случае затенены и переименованы.

Ответ на самом деле заключается в том, что вам нужно самостоятельно протестировать его на конкретной платформе, которая вас интересует.

17 голосов
/ 03 февраля 2010

Действительно ли соглашение о вызовах fastcall действительно быстрее, чем другие соглашения о вызовах, такие как cdecl?

Я полагаю, что реализация Microsoft fastcall на x86 и x64 предполагает передачу первых двух параметров в регистры, а не в стек.

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

11 голосов
/ 03 февраля 2010

Соглашение о вызовах (по крайней мере, на x86) не сильно влияет на скорость. В Windows _stdcall был установлен по умолчанию, потому что он дает ощутимые результаты для нетривиальных программ в том смысле, что он обычно приводит к меньшему размеру кода по сравнению с _cdecl. _fastcall не является значением по умолчанию, потому что разница, которую он делает, гораздо менее ощутима. То, что вы компенсируете при передаче аргументов через регистры, вы теряете в менее эффективных телах функций (как ранее упоминалось Anon.). Вы ничего не получаете, передавая регистры, если вызываемая функция немедленно должна вылить все в память для своих собственных вычислений.

Однако мы можем выдвигать теоретические идеи в течение всего дня - сравните ваш код для правильного ответа. _fastcall будет быстрее в некоторых случаях и медленнее в других.

10 голосов
/ 03 февраля 2010

на современном x86 - нет.Между кэш-памятью L1 и встроенной памятью нет места для fastcall.

...