其他分享
首页 > 其他分享> > c – 为什么std :: optional的构造比std :: pair更昂贵?

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

live example on godbolt.org

为什么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