【发布时间】:2014-10-12 10:54:21
【问题描述】:
x86-64 ABI 指定两个返回寄存器:rax 和 rdx,大小均为 64 位(8 字节)。
假设 x86-64 是唯一的目标平台,这两个功能中的哪一个:
uint64_t f(uint64_t * const secondReturnValue) {
/* Calculate a and b. */
*secondReturnValue = b;
return a;
}
std::pair<uint64_t, uint64_t> g() {
/* Calculate a and b, same as in f() above. */
return { a, b };
}
考虑到针对 x86-64 的 C/C++ 编译器的当前状态,会产生更好的性能吗?使用一个或另一个版本在性能方面是否存在任何缺陷?编译器(GCC、Clang)是否总是能够优化 std::pair 以在 rax 和 rdx 中返回?
更新: 通常,如果编译器优化了 std::pair 方法(GCC 5.3.0 和 Clang 3.8.0 的二进制输出示例),则返回一对会更快。如果f() 没有内联,编译器必须生成代码来将值写入内存,例如:
movq b, (%rdi)
movq a, %rax
retq
但如果是g(),编译器就足够了:
movq a, %rax
movq b, %rdx
retq
因为将值写入内存的指令通常比将值写入寄存器的指令慢,所以第二个版本应该更快。
【问题讨论】:
-
您是否尝试测量性能?
-
你真的需要这么小的性能吗?
-
@Sathish 这是有效的语法。相当于
return std::pair<uint64_t, uint64_t>{a, b}; -
@Sathish:您可以返回一个包含 2 个数字的结构。 x86-64 ABI 表示,在特定情况下,它会在 2 个寄存器中返回。
-
您是否尝试过查看发出的程序集?您是在寻找仅 Unix 的答案(给定编译器)还是对 MSVC 的答案也感兴趣? (它使用不同的 ABI)
标签: c++ c performance x86-64 abi