Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does argument order for the C calling convention ever have a performance impact?

Tags:

c

optimization

For example, would the functions:

void foo(float*,float*,int,float);
void foo(float*,float,float*,int);

have the same or different overhead?

Edit: I'm not asking about how the compiler will optimize things. I'm specifically asking in relation to the cdecl calling convention how overheads will be different on various ABIs.

like image 493
Mike Izbicki Avatar asked Jul 03 '15 21:07

Mike Izbicki


2 Answers

Traditional calling conventions will almost always allocate parameter space on the stack, and there is always overhead associated with copying arguments into this space.

Assuming a strictly volatile environment, the only additional overhead that can potentially exist can arise from memory alignment issues. In your given example, the parameters will be in contiguous memory and so there won't be any padding to align properly.

In the case of parameters with types of varying sizes, the parameters in the following declaration:

int func (int a, char c, int b)

will have padding between them, whereas those in this declaration:

int func (int a, int b, char c)

will not.

The stack frame for the former might look like:

| local vars... |                  low memory
+---------------+ - frame pointer
| a | a | a | a |
| c | X | X | X |
| b | b | b | b |
+---------------+                  high memory

And for the latter:

| local vars... |                  low memory
+---------------+ - frame pointer
| a | a | a | a |
| b | b | b | b |
| c | X | X | X |
+---------------+                  high memory

When the function gets called, the arguments will be written into the stack memory in the order they appear, so for the former you'll write the 4 bytes of int a, the 1 byte of char c, then you need to skip those 3 bytes to write the 4 bytes of int b.

In the latter, you'll be writing into contiguous memory locations, and won't need to account for skips due to padding.

In a volatile environment, we're talking about a difference in performance on the order of several nanoseconds for the skips. The performance hit may be detectable but almost negligible.

(By the way, how skipping is done is entirely architecture-dependent...but I'd bet in general it is just a higher offset for the next address to fill. I'm not completely sure how this might be done differently in different architectures).

Of course, in a non-volatile environment, when we utilize CPU caching, the performance hit goes down to fractions of a nanosecond. We'd be venturing into the undetectable, and so the difference is effectively nonexistent.

Data padding is really only a space cost. When you're working in embedded systems, you'll want to order your parameters from largest to smallest to reduce (and sometimes eliminate) padding.

So, as far as I can tell (without further information like the exact data transfer rates between memory on a particular machine or architecture), there shouldn't be a performance hit for different parameter orders.

like image 191
Purag Avatar answered Oct 06 '22 09:10

Purag


Of course this kind of detail depends on the platform/ABI.

For example with x86-64 there should be no difference as this few parameters would be passed simply in registers and register use is almost symmetrical (so it doesn't really matter which register you want to use).

With more parameters there would be some stack spilling and in this case it could make a difference depending on how the spilled parameters are used in the body of the function.

For example if they're needed as a count for a loop then they can be used directly from the stack, if instead they're pointers then to dereference the pointed value they must be first moved into a register.

Note that of course what exactly happens is up to the compiler (even with just two parameters)... so it's not impossible that there are differences; what is impossible is using a specific order to get better result in general (i.e. independently from the compiler).

like image 37
6502 Avatar answered Oct 06 '22 09:10

6502