我很好奇为什么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()
的实现是否也做同样的事情?
提前谢谢。
答案 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
,发现它不是一个简单的循环。