gpt4 book ai didi

c++ - 为什么按值传递 string_view?为什么 Visual Studio 不能对此进行优化?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:50 24 4
gpt4 key购买 nike

根据我的直觉,我假设新的 string_view 需要通过引用传递,因为这样效率更高(只传递指针而不是完整的类)。然而,一些消息来源表明最好按值传递它,避免“别名”问题。

在尝试几种替代方案时,我证实了我的直觉,如果该函数只是转发 string_view(所有源均使用 /Ox 编译),那么通过引用传递会更快

比如这段代码

extern auto otherMethodByReference(const std::string_view &input) -> void;
auto thisMethodByReference(int value, const std::string_view &input) -> void
{
otherMethodByReference(input);
}

结果是这个程序集

00000   48 8b ca     mov     rcx, rdx
00003 e9 00 00 00 00 jmp ?otherMethodByReference@@YAXAEBV?$basic_string_view@DU?$char_traits@D@std@@@std@@@Z ; otherMethodByReference

虽然这段代码

extern auto otherMethodByValue(std::string_view input) -> void;
auto thisMethodByValue(int value, std::string_view input) -> void
{
otherMethodByValue(input);
}

结果是这个程序集

00000   48 83 ec 38  sub     rsp, 56            ; 00000038H
00004 0f 10 02 movups xmm0, XMMWORD PTR [rdx]
00007 48 8d 4c 24 20 lea rcx, QWORD PTR $T1[rsp]
0000c 0f 29 44 24 20 movaps XMMWORD PTR $T1[rsp], xmm0
00011 e8 00 00 00 00 call ?otherMethodByValue@@YAXV?$basic_string_view@DU?$char_traits@D@std@@@std@@@Z ; otherMethodByValue
00016 48 83 c4 38 add rsp, 56 ; 00000038H
0001a c3 ret 0

很明显,您可以看到在堆栈上创建了 string_view 的拷贝,然后将其传递给其他方法。

但是,我想知道,为什么编译器不对此进行优化,而是直接将 string_view 参数直接传递给另一个方法。毕竟,在 Windows x64 ABI 中,大于寄存器容量的类的按值传递总是通过复制堆栈上的寄存器,并在正确的寄存器中传递指向它的指针来完成的。我希望在这个示例代码中,编译器会简单地将指针转发到下一个函数,就像在按引用传递的情况下一样。毕竟,编译器可以看到参数的值之后没有被使用,所以它可以只转发地址而不是复制。

我尝试将 std::move 添加到调用中,如下所示:

auto thisMethodByValueAndMove(int value, std::string_view input) -> void
{
otherMethodByValue(std::move(input));
}

但这似乎没有帮助。

是否有 Visual Studio 2017 编译器无法对此进行优化的原因?其他编译器是否优化了这种模式?

最佳答案

X64 调用约定不允许在不同的寄存器之间传播参数。编译器可以通过 rcx 和 rdx 传递 string_view 但 ABI 反对这一点。 https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019

关于c++ - 为什么按值传递 string_view?为什么 Visual Studio 不能对此进行优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50675673/

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