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);
}
不过上边又说这样效率其实并不多高。很是郁闷。