2010-02-02 9 views
38

Czy konwencja wywoływania fastcall działa naprawdę szybciej niż inne konwencje wywoływania, takie jak cdecl? Czy są jakieś testy porównawcze pokazujące, w jaki sposób konwencja wywoływania wpływa na wydajność?Czy usługa fastcall jest naprawdę szybsza?

+5

"W jaki sposób skuteczność wpływa na konwencję wywoływania?" Marginalnie. – avakar

+12

Z wyjątkiem sytuacji, gdy ma to znaczny wpływ. – Crashworks

+1

Zobacz także http://bcbjournal.org/articles/vol4/0004/When_to_use___fastcall.htm?PHPSESSID=7ea0b77df8671b0af9001fbca735c1bc – bluish

Odpowiedz

30

To zależy od platformy. Przykładowo w przypadku Xenon PowerPC może to być różnica rzędów wielkości ze względu na problem z załadowaniem magazynu i przekazywaniem danych na stosie. I empirycznie czas narzut funkcji cdecl w około 45 cyklach w porównaniu do ~ 4 dla fastcall.

W przypadku nieoryginalnych x86 (Intel i AMD) wpływ może być znacznie mniejszy, ponieważ rejestry są w ogóle shadowowane i mają zmienioną nazwę.

Odpowiedź brzmi, że trzeba samemu sprawdzić to na konkretnej platformie, na której Ci zależy.

16

Czy konwencja wywoływania fastcall działa naprawdę szybciej niż inne konwencje wywoływania, takie jak cdecl?

Wierzę, że realizacja Microsoftu z fastcall na x86 i x64 polega na przepuszczeniu przez pierwsze dwa parametry w rejestrach zamiast na stosie.

Ponieważ zazwyczaj zapisuje co najmniej cztery dostępy do pamięci, tak, generalnie jest szybszy. Jeśli jednak funkcja ta nie jest zarejestrowana w rejestrze, a tym samym prawdopodobne jest zapisanie jej locals na stosie, prawdopodobnie nie będzie znacznego wzrostu.

+4

W x64 istnieje tylko jedna konwencja wywoływania –

10

Konwencja wywołania (przynajmniej na x86) nie ma większego wpływu na szybkość. W systemie Windows domyślnie ustawiono _stdcall, ponieważ daje on namacalne wyniki dla nietrywialnych programów, ponieważ zwykle skutkuje mniejszym rozmiarem kodu w porównaniu z _cdecl. _fastcall nie jest wartością domyślną, ponieważ różnica, którą tworzy, jest o wiele mniej namacalna. To, co nadrabiasz w argumentacji przechodzącej przez rejestry, tracisz w mniej wydajnych ciałach funkcyjnych (jak wspomniano wcześniej przez Anon.). Nic nie zyskujesz, przechodząc do rejestrów, jeśli wywoływana funkcja natychmiast musi wyrzucić wszystko do pamięci dla własnych obliczeń.

Jednak możemy przez cały dzień wylewać pomysły teoretyczne - testujemy twój kod pod kątem prawidłowej odpowiedzi. _fastcall będzie szybszy w niektórych przypadkach, a wolniejszy w innych.

8

Na nowoczesnym x86 - nie. Między pamięcią podręczną L1 a in-line nie ma miejsca na szybkie połączenia.

+10

Jeśli funkcja jest wstawiona, to nie jest fastcall ani cdecl ani żadna inna konwencja wywoływania. – Crashworks

+7

Dokładnie. Pobranie z L1 jest rejestrem przechodzącym 1 cykl - w większości przypadków jest poniżej poziomu hałasu, trudno jest go nawet bezbłędnie zmierzyć. A funkcje, w przypadku których kilka cykli jest ważną różnicą, powinny być i tak podkreślone. – ima

+1

Muszę się z tym zgodzić - każda funkcja, która byłaby na tyle prosta, aby skorzystać z funkcji FastCall, zyskałaby na dodaniu jeszcze więcej. –

Powiązane problemy