Skip to main content
GameDev.net gamedev.net
🔒 Locked

_stdcall vs. _fastcall

Started by caldiar Jan 20, 2008 at 4:45 PM 7 replies 3.3k views
Original Post
caldiar
caldiar
I've been reading an article on C++ optimization techniques and one thing that was mentioned was to use _fastcall in your programs because it was considerably faster than _cdecl. I noticed that _stdcall was also faster than _cdecl and I've been wondering if there is some sort of situation where I should be using _stdcall instead of _fastcall? Or has _fastcall made _stdcall outdated and I should just stick with the advice given by the article? Thanks, Caldiar
VanillaSnake21
VanillaSnake21
I think that there are some cases when you have to pass arguments using the stack
(__stdcall) such as function with variable number of arguments ex "function(int x, ...)" The stack can handle any number of arguments but i don't think you can do that with registers (__fastcall).
You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts
fpsgamer
fpsgamer
Let your compiler sort it out. It can choose the calling convention fairly effectively by itself.

Besides __stdcall is in no way outdated. What do you think happens when all your arguments cant fit into registers?
SiCrane
SiCrane
Compilers don't choose calling conventions; they need to be specified by the coder: either explicitly by using one of the calling convention attributes or implicitly by compiler settings. For example, MSVC uses __cdecl for all functions without an explicit calling convention if /Gd is used (which is default), but uses __fastcall for all functions without an explicit calling convention if /Gr is used.
Adam_42
Adam_42
In addition to what's been said already, if function call overhead is causing you performance issues then by far the simplest and quickest solution is to make sure those functions gets inlined. The compiler will probably do that for you automatically in most cases anyway.

It can also be worthwhile to minimize the number of parameters you pass to functions in some cases (like say recursive functions which generally won't get inlined). Passing large structures / classes by value will obviously also be slow, use references or pointers instead.

Also note that in C++ the this pointer is passed in a register (ecx) anyway.
Jerax
Jerax
Quote:
Original post by VanillaSnake21
I think that there are some cases when you have to pass arguments using the stack
(__stdcall) such as function with variable number of arguments ex "function(int x, ...)" The stack can handle any number of arguments but i don't think you can do that with registers (__fastcall).


Varargs are passed __cdecl, as __stdcall and __fastcall aren't able to cleanup the stack correctly.

__stdcall can result in slightly smaller code, especially if you do a lot of function calling.

Also as Adam_42 says, these calling conventions are only for free/static functions. Member functions are always called as "thiscall", where this is passed in ecx, and all other arguments are on the stack.


Also note, the above is only for MSVC, different compilers pass arguments in different ways.
Antheus
Antheus
If a function call overhead becomes/is-by-design a problem, factor the function call out. For example, if you know that a function will be called frequently (tens/hundreds of millions of times per second), then remove the function call.

Calling conventions don't matter enough to be worth it, since inlining is where the big benefits lie. These days, bottle-necks at this granularity come from memory access, so preventing that will generally dwarf any benefits obtained by function call anyway.

fastcall is also MSVC specific, and as such a rather poor choice. It's also very easy to run into linking problems when mixing calling conventions.

But again, it's very very rarely that the function calling mechanism will be the bottle-neck. The obvious solution is just too trivial - prefer to not call the function.
caldiar
caldiar
Thank you very much for the responses everyone. They're exactly what I was looking for and they clear up my confusion :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.