为什么memcpy()更快?

时间:2013-03-30 22:28:33

标签: c memcpy

我很好奇为什么memcpy()函数比简单的手动副本更快。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main() 
{ 
    clock_t begin, end;
    double time_spent;
    int i, j;   
    char source[65536], destination[65536]; 

    begin = clock();

    for (j = 0; j<1000; j++) 
        for (i = 0; i < 65536; i++) destination[i] = source[i];
    //slower than memcpy(destination, source, 65536);

    end = clock();
    time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("%Lf\n",time_spent);
    system("pause");
} 

memcpy()的实现是否也做同样的事情? 提前谢谢。

7 个答案:

答案 0 :(得分:4)

一个好的优化编译器应该确定你的循环实际上是memmove()或memcpy(),并用对该函数的调用替换它。这仍然留下了一个问题:为什么这样做很聪明?

事实证明,用于复制内存的编译代码的手动优化有很大的空间,并且编译器还不够智能(它也是非常特定于cpu的,因此操作系统将具有它们支持的每个CPU系列的专用版本,并在运行时交换它们。

这是OSX的x86_64 SSE 4.2副本实现:http://www.opensource.apple.com/source/Libc/Libc-825.25/x86_64/string/bcopy_sse42.s

答案 1 :(得分:3)

memcpy()可以包含各种其他优化,例如SIMD。有关详细信息,请参阅this answer

答案 2 :(得分:3)

  

memcpy()的实现是否做同样的事情?

不一定。

这是一个标准的库函数,因此:

  • 它可以使用特定于平台的快速汇编指令进行高度优化,也可以只复制每次迭代多个字节,如果处理器有足够大的寄存器,则会更快;
  • 它可能被编译器识别为内置函数,因此它可以执行更多优化步骤,例如,内联它删除函数调用开销,或从其上下文中推断出您尝试执行的操作并使用另一个执行此操作方法等。

答案 3 :(得分:1)

因为for循环逐个复制项目。而memcpy()逐块复制项目。您可以在此处阅读memcpy()的源代码:https://www.student.cs.uwaterloo.ca/~cs350/common/os161-src-html/memcpy_8c-source.html或此处http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/memcpy.c.htm

答案 4 :(得分:1)

memcpy()将尝试一次复制字,即32位系统上每次迭代4个字节,64位系统上每次迭代8个字节。

答案 5 :(得分:0)

memcpy不是一个香草循环。有许多优化措施。

像对齐和字大小这样的东西允许memcpy以更稳定的速度复制更大块的内存。

答案 6 :(得分:0)

你可以进入memcpy,发现它不是一个简单的循环。