文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>哪个memcpy更快?

哪个memcpy更快?

时间:2010-06-20  来源:raise_sail

    在复习Linux文件系统的代码,看到一段代码,想起来好像与“代码优化”一书中介绍的原理颇为契合,于是操刀编译试了试,最后焦点集中在了memcpy身上。试验的结果晒一下:

kernel:

static inline char *std_memcpy(char *to, char *from, int n)
{
int d0, d1, d2;
asm volatile ("rep ; movsl\n\t"
"movl %4,%%ecx\n\t"
"andl $3,%%ecx\n\t"
"jz 1f\n\t"
"rep ; movsb\n\t"
"1:":"=&c" (d0), "=&D"(d1), "=&S"(d2):"0"(n / 4),
"g"(n), "1"((long) to), "2"((long) from):"memory");
return to;
}



unroll:

static inline char* std_memcpy(char *dst, char *src, unsigned int sz)
{
   int n;
   unsigned long long *srcp, *dstp;
   char *r = dst;

  n = sz & (sizeof(unsigned long long) - 1);
  while (n-- && (*dst++ = *src++))

    ;

  n = sz & ~(sizeof(unsigned long long) - 1);
  srcp = (unsigned long long *) src;
  dstp = (unsigned long long *) dst;

  while (n && (*dstp++ = *srcp++))
     n -= sizeof(unsigned long long);
  return r;
}


working(more unroll):

static inline char* std_memcpy(char *dst, char *src, unsigned int sz)
{
int n;
unsigned long long *srcp, *dstp;
char *r = dst;

n = sz & ((sizeof(unsigned long long)<<1) - 1);
while (n--)
   *dst++ = *src++;

  n = sz & ~((sizeof(unsigned long long)<<1) - 1);
  srcp = (unsigned long long *) src;
  dstp = (unsigned long long *) dst;

while (n) {
  *dstp++ = *srcp++;
  *dstp++ = *srcp++;
  n -= sizeof(unsigned long long)<<1;
}
return r;


结果:

测试平台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


文件: strcpy.tar.gz
大小: 2KB
: 下载
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载