闲着没事测了一下memcpy

本文通过对比自己编写的 memcpy、Linux 内核的 __memcpy 和 glibc 的 memcpy,揭示了性能差异的原因。测试显示,内核和 glibc 的实现优于自定义版本,且 glibc 在用户空间表现更优。分析指出,优化主要在于内存操作的批量处理和利用总线位宽。此外,缓冲区大小不同,性能差异主要在于寻址时间。源码分析和测试结果显示,memcpy 的性能与其处理的块尺寸密切相关,过大或过小都会带来额外开销。
摘要由CSDN通过智能技术生成

前阵的时候领导提出要对memcpy做一个测试。也没有交代具体的细节。我就直接自已写了个常规memcpy,然后再把内核的__memcpyglibcmemcpy整出来,对三者进行比较,不比不知道,一比吓一大跳。

测试结论是:

kernel和glibc的memcpy性能良好,glibc比内核的略高。自已写的就惨不忍睹了。

测试程序大概是先定义两块1G的全局内存。然后先用memset将其全置为1或者其它数。原理道上的兄弟都知道,linux内核很聪明,只要在你实际要用的到的时候才会产生缺页中断为你分配内存,否则只会在虚拟内存映射表中占个位置。

接下来就是循环拷贝了。

通过对每次拷贝的buffersize设置不同的值,发现不论是linux还是glibc中的memcpy效率都会有惊人的差异。

另外可以看来glibcmemcpy在用户空间几乎是完胜内核的memcpy的。我后面看了一下glibc的代码,发现glibcmemcpy对传入的长度做了精细的判断再调用不同的内嵌汇编代码。linux内核的memcpy相比glibc就简洁多了。

 

其实我们感兴趣的主要有两个:

1.内核和glibcmemcpy为什么比我们自已写的性能高这么多?

2.为什么buffersize不一样,性能差异会这么大?

OK,我们先来分析第一个问题.

请看。

常规的memcpy是:

inline int mymemcpy(char *dest,char *src,int len)

{

    while(len--){

        *(dest++) = *(src++);

    }

    return 0;

}

在不加优化选项的情况下反汇编后如下:

   0x08048354 <+0>:     push   %ebp

   0x08048355 <+1>:     mov    %esp,%ebp

   0x08048357 <+3>:     jmp    0x804836c <mymemcpy+24>

   0x08048359 <+5>:     mov    0xc(%ebp),%eax  //内存操作

   0x0804835c <+8>:     movzbl (%eax),%edx      //内存操作

   0x0804835f <+11>:    mov    0x8(%ebp),%eax  //内存操作

   0x08048362 <+14>:    mov    %dl,(%eax)      //内存操作

   0x08048364 <+16>:    addl   $0x1,0x8(%ebp)   //内存操作

   0x08048368 <+20>:    addl   $0x1,0xc(%ebp)   //内存操作

   0x0804836c <+24>:    subl   $0x1,0x10(%ebp)  //内存操作

   0x08048370 <+28>:    cmpl   $0xffffffff,0x10(%ebp) //内存操作

   0x08048374 <+32>:    jne    0x8048359 <mymemcpy+5> //立即数操作

   0x08048376 <+34>:    mov    $0x0,%eax

   0x0804837b <+39>:    pop    %ebp

   0x0804837c <+40>:    ret 

 

内核的memcpy:

static void *__memcpy(void *to, const void *from, int n)

{

    int d0, d1, d2;

    asm volatile("rep ; movsl/n/t"

            "movl %4,%%ecx/n/t" 

            "andl $3,%%ecx/n/t"

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值