memcpy实现及其优化
2018-08-23 本文已影响0人
執著我們的執著
1. 版本一
void *memcpy(void * pDest, const void *pSrc, unsigned int n)
{
assert((NULL != pDest)&&(NULL != pSrc));
char *pTmpDest = (char *)pDest;
char *pTmpSrc = (char *)pSrc;
while(n)
{
*pTmpDest = *pTmpSrc;
pTmpDest ++;
pTmpSrc ++;
}
return pDest;
}
/********************************************/
未考虑源和目的内存地址重叠,可以直接增加内存地址重叠判断
assert(pDest>=pSrc+n || pSrc>pDest+n);
/********************************************/
此外也可以实现即使内存地址重叠,也进行copy操作,不做多余阐述
2. 版本2:改进
分析:版本一的memcpy
实现的是char到char的拷贝的循环,效率可能不高,实际上,标准库中的memcpy
是一个效率很高的内存拷贝函数,他不会逐个字节的copy,在地址不对齐的情况下,他是逐字节copy,地址对齐后,就会使用CPU字长来copy,(32bits或64bits),此外还会根据cpu的类型来选择一些优化的指令来进行拷贝。总的来说,memcpy的实现是和CPU类型、操作系统、cLib相关的。
下面实现CPU字长为4个字节,对齐状态按32bits(4个字节)来copy
void *Upgrade_memcpy(void *pDest,const void *pSrc,size_t n)
{
assert((pDest!=NULL)&&(pSrc!=NULL));
int wordnum = n/4; //计算有多少个32位,按4字节拷贝
int slice = n%4; //剩余的按字节拷贝
int * pIntsrc = (int *)pSrc;
int * pIntdest = (int *)pDest;
while(wordnum--)
*pIntdest++ = *pIntsrc++;
while (slice--)
*((char *)pIntdest++) =*((char *)pIntsrc++);
return pDest;
}