memcpy的8位,16位,32位分别实现

今天面试碰到一道题,大致意思是: memcpy的原型是 void   * my_memcpy( void   * dst,  void *  src,  int  size) ,请分别用 8位,16位,32位分别实现。

8位当然很简单了。然后也想到了这个参数 dst,src的指针返回时是原值,所以里面要用一个临时指针去算。 16和32 的时候,最后 余下来的部分还是要 按 8位来拷贝的,但是 这样的话16和32位又是一样的了,但又想不出来。后来路上想起来 ,那个返回值自己忘记了。

回到家,网上查了下这个实现,发现其实这是一个效率的问题。三种实现那种效率好呢?可能你会说当然是 32位。原因是:
考虑的角度是充分利用 cpu 的 32 位带宽。一次复制 1 个字节和一次复制 4 个字节占用的 cpu 指令周期是一样的,既然我们的 cpu 能同时操作 32 位,为什么我们不能一次复制 4 个字节呢?如此一来,总运行的指令数将降低到原来的 1/4 !

但一定是这样吗?不一定。如果上面的src ,dst不是4字节对齐呢?分析如下:

在地址按4 字节对齐的时候,上述算法的效率比单字节 memcpy 实现高很多,但如果地址没有按4 字节对齐,则其效率并不高,有时甚至还比普通 memcpy 还低。这可能是因为,虽然上述算法减少了 cpu 的指令数,但内存的速度比 cpu 慢得多,速度的瓶颈还是在内存。(http://www.cnblogs.com/shapherd/archive/2010/05/19/1739628.html)

还看到了老外对这个问题的探讨 http://www.eetimes.com/design/other/4024961/Optimizing-Memcpy-improves-speed

原文地址:http://blog.chinaunix.net/uid-10696433-id-2935799.html


以上是转载,今天笔试这样一道题目:32位机 高效实现memcpy,当时没有考虑“高效”,用的是char型的现在看来下边这样gnu的是最好的。

Listing 2: The modified-GNU algorithm

void * memcpy(void * dst, void const * src, size_t len)
{
    long * plDst = (long *) dst;
    long const * plSrc = (long const *) src;

    if (!(src & 0x03) && !(dst & 0x03)) //判断内存对齐(4的位数)
    {
        while (len >= 4)
    {
            *plDst++ = *plSrc++;
            len -= 4;
        }
    }

    unsigned char * pcDst = (unsigned  char *) plDst;
    unsigned char const * pcDst = (unsigned char const *) plSrc;

    while (len--)
    {
        *pcDst++ = *pcSrc++;
    }

    return (dst);
}

转自: http://www.embedded.com/design/configurable-systems/4024961/Optimizing-Memcpy-improves-speed

不过上边又说这样效率其实并不多高。很是郁闷。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值