memcpy提高效率
代码如下:
- C/C++ code
#include<stdio.h>#include<string.h>#include<time.h>char dest[65536],source[65536];void dumpcopy(){ for(int i=0;i<10000;i++) for(int i=0;i<65536;++i){ dest[i]=source[i]; }}void smartcopy(){ for(int i=0;i<10000;i++) memcpy(dest,source,65536);}int main(){ clock_t start,middle,end; start=clock(); dumpcopy(); middle=clock(); smartcopy(); end=clock(); printf("%.20f\n",(middle-start)/(double)CLOCKS_PER_SEC);//约2.2s printf("%.20f\n",(end-middle)/(double)CLOCKS_PER_SEC);//约0.07s return 0;}测试了下占用CPU时间,大约是2.2s和0.07s
为什么调用memcpy提高了速度,本身memcpy是函数调用,有函数开销,反而性能提高了
<<C 专家编程>>P151 书上原话:
之所以出现性能下降,是因为source和destination的大小正好都是Cache的容量的整数倍,SS2上的Cache并行不是按顺序填充的--它使用一种特殊的算法,填充于同一Cache行的主存地址恰好是该Cache行大小的整数倍,这是因为存储优化引起的--在这种设计方法中,只有地址的高位才被放入标签中,这样一来,source和destination便不可同时出现在cache中,于是导致了性能显著下降。
在这个source和destination都使用同一个Cache行的特殊情况下,会导致每次对内存的引用都无法命中Cache,使CPU利用率大大降低,因为他不得不等待常规操作的内存操作完成。
库函数memcpy()经过特别的优化以提高性能,它把先读取一个Cache行再对它进行写入这个循环分开,这就避免了上述问题。
我没看懂,不吝赐教,先谢谢了
[解决办法]
额……翻译得比较绕口,或者可以说翻译有问题。我也看不明白。
但大意是说:
1.source和destination在默认的存储优化中,是无法共存于Cache中的,每次读写source和destination时,都要去内存中操作,导致了所需时间大大延长。
2.memcpy把source和destination进行了拆分,然后进行循环读写,避免了所谓的存储优化,使得source和destination能共存于Cache中,而不用每次都去内存中进行操作。
这是我的理解,不过最好还是去看看英文原版,这个翻译太扯淡了。
[解决办法]
不知道从哪里翻译出来的,看不懂。
不过可以肯定楼主是在Debug模式下测试的。在我看来,就仅仅是代码效率的差别。memcpy的具体传送在一条指令里完成,而且使用的是SSE指令,传送速度非常快。而直接的数组复制在传送时使用的代码太多(不止是循环语句,那里面还包含着用于调试的很多东西哪),计算速度当然就慢很多了。
经测试,如果采用release版本编译,这两段代码会被译成同样的形式,执行时间相同。
[解决办法]
1 慢的原因是因为,
source和destination 无法同时 从内存 放到cache中,
因此每做一个字符的拷贝,都要
a. 把src 读取到cache中
b cache 到寄存器
c 把dst读取到cache (src已经被覆盖了)
d cache到寄存器
e mov 操作
但是编译器提供的 memcpy
估计是用了 ss2 的指令,
每次可以读取多个字符,然后拷贝多个字符
这样就减少了 从内存到cache的来回操作。
[解决办法]
深入理解计算机系统
第6章, 不必抠字,理解是关键