全部博文(18)
分类: C/C++
2010-06-20 19:28:30
在复习Linux文件系统的代码,看到一段代码,想起来好像与“代码优化”一书中介绍的原理颇为契合,于是操刀编译试了试,最后焦点集中在了memcpy身上。试验的结果晒一下:
kernel:
static inline char *std_memcpy(char *to, char *from, int n) |
static inline char* std_memcpy(char *dst, char *src, unsigned int sz) ; n = sz & ~(sizeof(unsigned long long) - 1); |
static inline char* std_memcpy(char *dst, char *src, unsigned int sz) |
结果:
测试平台1:
CPU:Intel(R) Pentium(R) M processor 1.60GHz
内存:1GB
gcc选项:-fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -march=nocona -mno-red-zone -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -fstack-protector-all -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-mmx -mno-3dnow -fomit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -mno-sse2 -mno-sse -m32 -Wall (为内核编译所用)
有图有真相,分别以复制512Bytes, 4KB, 512KB, 1MB, 2MB的数据展示结果:(横轴是用例编号,时间差是用rdtsc读出来的;std即为C库代码)
测试平台2:
AMD Athlon(tm) 64 X2 Dual Core Processor 5000+
内存:2GB
GCC选项同上。
同样示出类似AMD平台的结果:
结论
2.6.31内核的memcpy很NB
较新的x86机器上,混合内存读写事务对性能影响不大
从性能表现上看,AMD和Intel机器的行为很接近。
AMD机器的表现似乎不太稳定,相同测试中的跳跃比较大,但我测试Intel与AMD的软件环境不同,这点结论可能不足为凭。
C库中的memcpy()得试完再用,性能不是想像中的那么high:
在复制少量数据时(<4KB),显然标准的memcpy并不占任何优势。
在复制大量数据时( >1MB),所有方法似乎都差不多,但kernel和标准的stdcpy的性能表现更稳定一些。
上面的优化方法很简单,就是循环展开,我们可以用ANSI
C写出更快的memcpy么?下面我试验的完整代码,绘制图片要求使用gnuplot 4.2 patchlevel 5
|
hengyunabc2011-12-11 00:28:38
貌似std_memcpy算法有问题,没有考虑到字节对齐的问题。
比如要复制99个字节算,按上面的unroll算法,是复制3个字节,再整8个地复制。
考虑到malloc分配到的内存一般是4字节对齐的。在long long赋值给另一个long long时要进行两次内存写操作。
??