拷贝与引用基准测试:对象何时不再通过寄存器传递?
函数传值与传引用的寄存器传递界限探究
我了解到函数调用时小型对象会通过CPU寄存器传递,尝试探寻该规则不再适用的界限。已知string_view会通过寄存器传递,但不清楚具体限制。尽管这与架构相关,但测试发现即便较大的对象也可通过寄存器传递。
测试代码如下:
struct big_object { int a_; double b_; char c_; long long d_; bool e_; int f_; double g_; char h_; long long i_; bool j_; int k_; double l_; char m_; long long n_; bool o_; }; big_object obj = { .a_ = 2, .b_ = 2.5, .c_ = 'A', .d_ = 1203912045891732283, .e_ = false, .f_ = 10, .g_ = 15.5, .h_ = 'D', .i_ = 123123123, .j_ = true, .k_ = 10, .l_ = 15.5, .m_ = 'D', .n_ = 123123123, .o_ = true, }; volatile int a; volatile double b; volatile char c; volatile long long d; volatile bool e; volatile int f; volatile double g; volatile char h; volatile long long i; volatile bool j; volatile int k; volatile double l; volatile char m; volatile long long n; volatile bool o; int foo(big_object obj) { a = obj.a_; b = obj.b_; c = obj.c_; d = obj.d_; e = obj.e_; f = obj.f_; g = obj.g_; h = obj.h_; i = obj.i_; j = obj.j_; k = obj.k_; l = obj.l_; m = obj.m_; n = obj.n_; o = obj.o_; return 1; } int foo_ref(big_object& obj) { a = obj.a_; b = obj.b_; c = obj.c_; d = obj.d_; e = obj.e_; f = obj.f_; g = obj.g_; h = obj.h_; i = obj.i_; j = obj.j_; k = obj.k_; l = obj.l_; m = obj.m_; n = obj.n_; o = obj.o_; return 1; } static void Foo(benchmark::State& state) { // Code inside this loop is measured repeatedly for (auto _ : state) { foo(obj); } } // Register the function as a benchmark BENCHMARK(Foo); static void FooRef(benchmark::State& state) { // Code before the loop is not measured for (auto _ : state) { foo_ref(obj); } } BENCHMARK(FooRef);
上述代码编译后,传值与传引用版本生成的汇编代码完全一致,性能表现相同。我虽不精通汇编,但能看到大量寄存器被用于传递对象。考虑到物理CPU寄存器数量多于逻辑寄存器,这是否意味着在实际场景中传引用完全多余?
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

