您的位置:首页 > 其它

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

2013-05-13 21:30 399 查看
今天面试碰到一道题,大致意思是: 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
不过上边又说这样效率其实并不多高。很是郁闷。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: