c - 用于图像处理的非常快的 memcpy?

标签 c assembly optimization x86 memcpy

我正在用 C 语言进行图像处理,这需要在内存中复制大量数据——源和目标永远不会重叠。

使用 GCC 在 x86 平台上执行此操作的绝对最快方法是什么? (哪里可以使用 SSE,SSE2 但不是 SSE3)?

我希望解决方案是在汇编中还是使用 GCC 内部函数?

我找到了以下链接,但不知道它是否是最好的方法(作者还说它有一些错误):http://coding.derkeiler.com/Archive/Assembler/comp.lang.asm.x86/2006-02/msg00123.html

编辑:请注意,副本是必要的,我无法绕过必须复制数据(我可以解释原因,但我会省去你的解释:))

最佳答案

William Chan 提供和谷歌。比 Microsoft Visual Studio 2005 中的 memcpy 快 30-70%。

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:
  }
}

您可以根据您的具体情况和您能够做出的任何假设进一步优化它。

您可能还想查看 memcpy 源代码 (memcpy.asm) 并删除其特殊情况处理。有可能进一步优化!

关于c - 用于图像处理的非常快的 memcpy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1715224/

相关文章:

c++ - 在准确的时间运行代码,la crond/atd

c - 在 C 中初始化结构数组

c++ - 无法交换值

8086 资源的汇编语言

c++ - 使用内联函数是否与直接在代码中编写函数体一样快?

c - 如何在c中缩放数字/数字范围

C/Java - 读取 2 个文件写入一个文件

gcc - 什么 '__asm__(".previous");'意思?

php - 使用多个 mysqli 对象或一个通用对象

sql - 加速使用 exists 的 sql 查询