gpt4 book ai didi

c++ - 返回与。指针

转载 作者:行者123 更新时间:2023-12-03 07:11:55 25 4
gpt4 key购买 nike

这两种情况之间的性能差异有多大?

int func(int a, int b) { return a + b; }
void func(int a, int b, int * c) { *c = a + b; }
现在,如果它是一个结构怎么办?
typedef struct { int a; int b; char c; } my;

my func(int a, int b, char c) { my x; x.a = a; x.b = b; x.c = c; return x; }
void func(int a, int b, int c, my * x) { x->a = a; x->b = b; x->c = c; }
我能想到的一件事是寄存器不能用于此目的,对吗?除此之外,我不知道这个函数在通过编译器后会变成什么样子。
哪个更高效、更快捷?

最佳答案

如果函数可以内联,前2个往往没有区别。
否则(因为没有链接时优化,所以没有内联)返回 int按值计算效率更高,因为它只是寄存器中的一个值,可以立即使用 .此外,调用者不必传递尽可能多的参数,或者找到/腾出空间来指向。如果调用者确实想要使用输出值,则必须重新加载它,从而在从输入就绪到输出就绪的整个依赖链中引入延迟。 (在现代 x86 CPU 上,存储转发延迟约为 5 个周期,而 lea eax, [rdi + rsi] 为 x86-64 System V 实现该功能的 1 个周期延迟。
异常(exception)情况可能是调用者不打算使用该值的极少数情况,只是希望它在某个地址的内存中。将该地址传递给被调用者(在寄存器中)以便可以在那里使用它意味着调用者不必将该地址保留在函数调用中可以存活的任何地方。

对于结构版本:

a register cannot be used for this purpose, correct?


不,对于某些调用约定,可以在寄存器中返回小结构。
x86-64 System V 将返回您的 my在 RDX:RAX 寄存器对中按值构造结构,因为它小于 16 个字节并且都是整数。 (并且可以轻松复制。)在 https://godbolt.org/z/x73cEh 上尝试一下-
# clang11.0 -O3 for x86-64 SysV
func_val:
shl rsi, 32
mov eax, edi
or rax, rsi # (uint64_t)b<<32 | a; the low 64 bits of the struct
# c was already in EDX, the low half of RDX; clang leaves it there.
ret
func_out:
mov dword ptr [rcx], edi
mov dword ptr [rcx + 4], esi # just store the struct members
mov byte ptr [rcx + 8], dl # to memory pointed-to by 4th arg
ret
GCC 不假定 char c以 clang 的方式正确符号扩展至 EDX ( unofficial ABI feature )。 GCC 做了一个非常愚蠢的字节存储/双字重载,它创建了一个存储转发停顿,从内存而不是 EDX 的高字节中获取未初始化的垃圾。纯粹是一个错过的优化,但在 https://godbolt.org/z/WGcqKc 中看到它.它还在执行 movq rax, xmm0 之前疯狂地使用 SSE2 将两个整数合并为 64 位值。 , 或输出参数的内存。
如果调用者使用这些值,您肯定希望 struct 版本内联,因此可以优化这种打包到返回值寄存器中。
How does function ACTUALLY return struct variable in C?有一个更大结构的 ARM 示例:按值返回将隐藏指针传递给调用者的返回值对象。从那里,如果分配给逃逸分析无法证明是私有(private)的东西,调用者可能需要从那里复制它。 (例如通过一些指针)。 What prevents the usage of a function argument as hidden pointer?
还相关: Why is tailcall optimization not performed for types of class MEMORY?
How do C compilers implement functions that return large structures?指出代码生成可能在 C 和 C++ 之间有所不同。
我不知道如何解释任何可以在不了解 asm 和您关心的调用约定的情况下应用的一般经验法则。通常通过引用传递/返回大型结构,但对于小型结构,它非常“取决于”。

关于c++ - 返回与。指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64740020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com