【问题标题】:Does any memcpy() implementation use multiple processor registers?是否有任何 memcpy() 实现使用多个处理器寄存器?
【发布时间】:2018-09-12 04:46:31
【问题描述】:

memcpy() 据我所知,通常实现为循环:

// Pseudo code - for illustration only
while(len--)
  ++*dst=++*src;

使用所有可用的 CPU 寄存器不是更有意义吗?!至少对于大副本?!

// Pseudo code - for illustration only
register srcA,dstA
register srcB,dstB
register srcC,dstC

while(len-=numreg)
{
  *dstA=*srcA;
  *dstB=*srcB;
  *dstC=*srcC;
}

所以问题是。 memcpy() 实现是否专门考虑了可用寄存器,还是留给编译器?!

【问题讨论】:

  • 如果您想知道,请使用 memcy() 并让编译器为您生成一个 .S 文件。或者在反汇编的调试器中跟踪它。我打赌你会看到各种各样的寄存器被使用。老实说,你几乎不想像以前那样编写代码。使用 std::memcpy() 并让优化器进入城镇,或者将一个结构分配给另一个结构,让优化器使用寄存器或 memcpy() 处理它。在这些情况下,它的判断力非常好 - 几乎比任何工程师都能诚实地判断。
  • "// 伪代码 - 仅用于说明" => "// 不可读的代码 - 仅用于说明"。这个问题没有意义。您认为 memcpy 是世界上每个程序都使用的核心功能,并没有在使用编译器的标准库中进行优化?
  • 我能读懂。写得不好,但我明白了它背后的想法......

标签: c optimization implementation memcpy cpu-registers


【解决方案1】:

使用所有可用的 CPU 寄存器不是更有意义吗?!在 至少对于大副本?!

是的。

最快的实现将使用寄存器在汇编程序中编码:

   void X_aligned_memcpy_sse2(void* dest, const void* src, const unsigned long size)
    {

      __asm
      {
        mov esi, src;    //src pointer
        mov edi, dest;   //dest pointer

        mov ebx, size;   //ebx is our counter 
        shr ebx, 7;      //divide by 128 (8 * 128bit registers)


        loop_copy:
          prefetchnta 128[ESI]; //SSE2 prefetch
          prefetchnta 160[ESI];
          prefetchnta 192[ESI];
          prefetchnta 224[ESI];

          movdqa xmm0, 0[ESI]; //move data from src to registers
          movdqa xmm1, 16[ESI];
          movdqa xmm2, 32[ESI];
          movdqa xmm3, 48[ESI];
          movdqa xmm4, 64[ESI];
          movdqa xmm5, 80[ESI];
          movdqa xmm6, 96[ESI];
          movdqa xmm7, 112[ESI];

          movntdq 0[EDI], xmm0; //move data from registers to dest
          movntdq 16[EDI], xmm1;
          movntdq 32[EDI], xmm2;
          movntdq 48[EDI], xmm3;
          movntdq 64[EDI], xmm4;
          movntdq 80[EDI], xmm5;
          movntdq 96[EDI], xmm6;
          movntdq 112[EDI], xmm7;

          add esi, 128;
          add edi, 128;
          dec ebx;

          jnz loop_copy; //loop please
        loop_copy_end:
      }
    }

来源: Very fast memcpy for image processing?

Blog: Improving memcpy for large memory copies

How to increase performance of memcpy

【讨论】:

  • 有点好奇,如果 memcpy() 是 4 个字节,它的效果如何?
  • 问题是关于 memcpy 函数。这个不关心将寄存器内容保存在堆栈上。标准功能不能这样实现
  • 哪种处理器型号最快?你知道专用处理器指令会定期检修,然后做最高效的事情吗?
  • @RichardChambers 感谢您的评论。我怀疑它快 4 个字节。但 OP 要求提供大副本。
  • @Deduplicator 你说的很对!它确实取决于处理器。这个是给英特尔的。消息来源声称在 Microsoft Visual Studio 2005 中比 memcpy 增加了 30-70%。
【解决方案2】:

首先你的伪代码是错误的,因为你忘了增加指针。当您考虑它时,您的优化将不再有意义。

另一个问题是你不能复制任何标准函数必须的字节数。

您当然可以使用特定的处理器功能为快速内存移动编写高度优化的函数,但作为标准 memcpy 函数的替代品,它几乎无法实现

【讨论】:

    猜你喜欢
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    相关资源
    最近更新 更多