c – 为什么std :: optional的构造比std :: pair更昂贵?
作者:互联网
考虑这两种可以表示“可选int”的方法:
using std_optional_int = std::optional<int>;
using my_optional_int = std::pair<int, bool>;
鉴于这两个功能……
auto get_std_optional_int() -> std_optional_int
{
return {42};
}
auto get_my_optional() -> my_optional_int
{
return {42, true};
}
… g trunk和clang trunk(-std = c 17 -Ofast -fno-exceptions -fno-rtti)生成以下程序集:
get_std_optional_int():
mov rax, rdi
mov DWORD PTR [rdi], 42
mov BYTE PTR [rdi+4], 1
ret
get_my_optional():
movabs rax, 4294967338 // == 0x 0000 0001 0000 002a
ret
为什么get_std_optional_int()需要三个mov指令,而get_my_optional()只需要一个movabs?这是QoI问题,还是std :: optional的规范中有什么阻止这种优化?
另请注意,无论如何,功能的用户可能会完全优化:
volatile int a = 0;
volatile int b = 0;
int main()
{
a = get_std_optional_int().value();
b = get_my_optional().first;
}
…结果是:
main:
mov DWORD PTR a[rip], 42
xor eax, eax
mov DWORD PTR b[rip], 42
ret
解决方法:
libstdc显然没有实现P0602 “variant and optional should propagate copy/move triviality”.您可以通过以下方式验证:
static_assert(std::is_trivially_copyable_v<std::optional<int>>);
which fails for libstdc++, and passes for libc++ and the MSVC standard library(真正需要一个正确的名称,所以我们不必称它为“C标准库的MSVC实现”或“MSVC STL”).
当然MSVC仍然不会传递一个可选的< int>在寄存器中因为MS ABI.
编辑:此问题已在GCC 8发布系列中修复.
标签:c,performance,assembly,x86-64,c17 来源: https://codeday.me/bug/20190928/1827157.html