I'm trying to understand the overhead of pass object by value as a function parameter in C++/Linux/x86-64 platform.
The experimental code I used for the exploration is posted below and on godbolt.org: https://godbolt.org/z/r9Yfv4
Assume the function is unary. What I observed is: 1) If the parameter object is a 8 bytes in size, it will be put in RDI. 2) If the parameter is 16 bytes in size (contain two sub-object each 8 bytes), the two sub-objects will be put in to RDI and RSI. 3) If the parameter is bigger than 16 bytes, it will be passed via stack. I only consider integral types and pointers and the composition types of these basic types. I know passing floats/doubles is different.
The size of std::function
is 32 bytes (GCC/Linux implementation, long + long + pointer + pointer = 32 bytes.). So passing std::function
by value should look like pass struct Person4
defined in my code. But the output assembly shows that pass std::function
is very different from pass struct Person4
. It looks like std::function is passed via a pointer, am I right? Why there is such a difference?
#include <functional> struct Person0 { long name; }; long GetName(Person0 p) { return p.name; } struct Person1 { long name; long age; }; long GetName(Person1 p) { return p.name; } struct Person2 { long name; long age; long height; }; long GetName(Person2 p) { return p.name; } struct Person3 { long name; long age; long height; long weight; }; long GetName(Person3 p) { return p.name + sizeof(p); } long Invoke(std::function<long(long)> f) { return f(20) + sizeof(f); } int main() { Person3 p; p.name = 13; p.age = 23; p.height = 33; p.weight = 43; long n = GetName(p); std::function<long(long)> ff; Invoke(ff); return 0; }
https://stackoverflow.com/questions/65838379/question-about-the-c-call-convention-of-passing-big-object-on-linux-x86-84 January 22, 2021 at 10:04AM
没有评论:
发表评论