I want to pass small (less than 64B) structs throught functions that I can't inline because they are used several times elsewhere and are quite big. But it still need it to be very fast.
Should I pass the structs directly (thus copying them) or use a pointer (and getting a dereference penalty) ?
My gut tells me to copy them, but you could always do a benchmark.
Name:
Anonymous2013-07-28 18:15
Depends on the calling convention. If it fits in a machine word, pass by value, the compiler will optimize it as if you passed in a integer variable. Some calling conventions use between 3-4 CPU registers to pass values to functions. In that case, the struct can be up to 3-4 machine words in size, and the compiler will pack it into the registers for you.
So on 64-bit machines, anything larger than 32 bytes should always be passed by references.
Name:
Anonymous2013-07-28 18:59
>>4
In no calling convention I have ever heard of will arguments be "packed" in registers. It's always one register per argument, and some CPUs have really weird additional contraints regarding sizes and alignment. Unless the struct is 4 members or less, use a pointer, unless you know exactly how your target platform works.
Name:
Anonymous2013-07-28 19:04
>>5
You don't know shit then. MSVC, GCC, and Clang will pack structs into registers on unexported/hidden functions for x64 and other platforms like ARM/ARM64.
Name:
Anonymous2013-07-28 19:11
>>6
There's no need to be mean. But if they are hidden functions they don't need to adhere to a calling convention, so >>6 doesn't contradict >>5.
Just tried it out, even in 32-bit 86, Clang will break a struct up and pass it in registers if the function isn't public. You can view the source and assembly output here:
>>7
Right, but most functions in most programs aren't public. Only when you're building shared libraries or DLLs do they become public, or you've explicitly defined them with a calling convention or as extern "C".