gpt4 book ai didi

c++ - 编译器选择不使用 REP MOVSB 指令进行字节数组移动

转载 作者:太空狗 更新时间:2023-10-29 20:51:14 25 4
gpt4 key购买 nike

我正在检查使用最新版本的 VS 2017 C++ 编译器完成的项目的发布版本。我很好奇为什么编译器选择构建以下代码片段:

//ncbSzBuffDataUsed of type INT32

UINT8* pDst = (UINT8*)(pMXB + 1);
UINT8* pSrc = (UINT8*)pDPE;
for(size_t i = 0; i < (size_t)ncbSzBuffDataUsed; i++)
{
pDst[i] = pSrc[i];
}

这样:

enter image description here

        UINT8* pDst = (UINT8*)(pMXB + 1);
UINT8* pSrc = (UINT8*)pDPE;
for(size_t i = 0; i < (size_t)ncbSzBuffDataUsed; i++)
00007FF66441251E 4C 63 C2 movsxd r8,edx
00007FF664412521 4C 2B D1 sub r10,rcx
00007FF664412524 0F 1F 40 00 nop dword ptr [rax]
00007FF664412528 0F 1F 84 00 00 00 00 00 nop dword ptr [rax+rax]

00007FF664412530 41 0F B6 04 0A movzx eax,byte ptr [r10+rcx]
{
pDst[i] = pSrc[i];
00007FF664412535 88 01 mov byte ptr [rcx],al
00007FF664412537 48 8D 49 01 lea rcx,[rcx+1]
00007FF66441253B 49 83 E8 01 sub r8,1
00007FF66441253F 75 EF jne _logDebugPrint_in_MainXchgBuffer+0A0h (07FF664412530h)
}

与仅使用单个 REP MOVSB 相比操作说明?后者不是更有效率吗?

最佳答案

编辑:首先,rep movsb 有一个内在函数,Peter Cordes 告诉我们这里会快得多,我相信他(我想我已经相信了)。如果您想强制编译器以这种方式做事,请参阅:__movsb(): https://learn.microsoft.com/en-us/cpp/intrinsics/movsb .

至于为什么编译器没有为你做这件事,在没有任何其他想法的情况下,答案可能是寄存器压力。要使用 rep movsb,编译器必须:

  • 设置rsi(=源地址)
  • 设置rdi(=目标地址)
  • 设置rcx(=计数)
  • 发出 rep movsb

所以现在它不得不用完 rep movsb 指令要求的三个寄存器,它可能不想这样做。特别是 rsirdi 应该在函数调用中保留,所以如果编译器可以在任何特定函数的主体中使用它们,它会,并且 (至少在初始进入该方法时)rcx 持有 this 指针。

此外,对于我们看到编译器在那里生成的代码,r10rcx 寄存器可能已经包含必要的源地址和目标地址(我们不能从你的例子中看到),如果是这样的话,这对编译器来说很方便。

在实践中,你可能会看到编译器在不同的情况下做出不同的选择。请求的优化类型(/O1 - 针对大小优化,与 /O2 - 针对速度优化)可能也会影响这一点。

更多关于 x64 寄存器传递约定 here ,并且在 x64 ABI 上通常为 here .


编辑 2(再次受到 Peter 评论的启发):

编译器可能决定不对循环进行矢量化,因为它不知道指针是否对齐或可能重叠。在没有看到更多代码的情况下,我们无法确定。但这与我的回答并不严格相关,考虑到 OP 实际询问的内容。

关于c++ - 编译器选择不使用 REP MOVSB 指令进行字节数组移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51120541/

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