1.为什么会写memcpy

在之前的应聘笔试上遇到一道笔试题,题目要求实现一个my_memcpy函数。函数原型:void * my_memcpy(void *dst, const void *src, int n);

之前使用的内存拷贝函数是标准库memcpy函数,拿来就用,真没有对这个函数做过多了解。在网上查了一下,有好多关于memcpy函数优化的文章。

在实现过程中了解的越多,往往实现起来越麻烦。还是先实现简单的memcpy函数。

2.按字节(Byte)拷贝实现的memcpy

 void *my_memcpy_byte(void *dst, const void *src, int n)
{
if (dst == NULL || src == NULL || n <= )
return NULL; char * pdst = (char *)dst;
char * psrc = (char *)src; if (pdst > psrc && pdst < psrc + n)
{
pdst = pdst + n - ;
psrc = psrc + n - ;
while (n--)
*pdst-- = *psrc--;
}
else
{
while (n--)
*pdst++ = *psrc++;
}
return dst;
}
    //20200104 看到评论,又看了下之前写的memcpy实现
    //按字节拷贝实现的memcpy没有问题
    //*pdst-- = *psrc--; 查了下运算符优先级(*,--)优先级相同,从右向左结合,psrc--是先使用,后减减
    //等价于*pdst = *psrc;psrc--;pdst--;

这里要考虑写覆盖的情况

3.按4字节拷贝实现的memcpy

 void *my_memcpy(void *dst, const void *src, int n)
{
if (dst == NULL || src == NULL || n <= )
return NULL; int * pdst = (int *)dst;
int * psrc = (int *)src;
char *tmp1 = NULL;
char *tmp2 = NULL;
int c1 = n / ;
int c2 = n % ; /*if (pdst > psrc && pdst < psrc + n) 这样判断有问题*/
if (pdst > psrc && pdst < (char *)psrc + n)
{
tmp1 = (char *)pdst + n - ;
tmp2 = (char *)psrc + n - ;
while(c2--)
*tmp1-- = *tmp2--;
/*这样有问题,忘记字节偏移
pdst = (int *)tmp1;
psrc = (int *)tmp2;
*/
tmp1++;tmp2++;
pdst = (int *)tmp1;
psrc = (int *)tmp2;
pdst--;psrc--;
while (c1--)
*pdst-- = *psrc--;
}
else
{
while (c1--)
*pdst++ = *psrc++;
35
36 tmp1 = (char *)pdst;
tmp2 = (char *)psrc;
while (c2--)
*tmp1++ = *tmp2++;
}
return dst;
}
      //20200104 查看评论说四字节写覆盖拷贝问题,现在已修改
      //备注:void *dst, const void *src这两个参数是需要按4字节对齐的,如果本身不是4字节对齐,按4字节拷贝效率也会变低。

这里还是考虑了写覆盖的代码。对比按字节拷贝,拷贝速度是提高不少。

以上是针对笔试过程中写memcpy。

4.如何优化memcpy

高性能的memcpy与很多因数相关,与平台,处理器,编译器,具体拷贝情形等相关。

VS2017中对C库的memcpy进行优化,glibc对memcpy也有优化

参考:怎样写出一个更快的 memset/memcpy ?

5.是否需要考虑内存对齐拷贝?

内存读写效率影响之一:内存对齐

参考:1.浅谈CPU内存访问要求对齐的原因     2.解析内存对齐

如果src,dst的地址是不对齐的,读写效率变低。

通过代码实现不对齐的拷贝,memcpy的实现会变得复杂,反而影响拷贝效率。

这种不对齐情况我们可以预先避免,因为编译器在给我们分配空间时是按照内存对齐进行分配的

6.根据拷贝数据大小进行优化

1.多次调用memcpy,而每次拷贝数据大小Kb下的小拷贝

  这种情况下尽量减少分支预测,代码精简。

2.拷贝Mb的memcpy实现

  这种情况影响拷贝效率主要在寻址上。

参考:闲着没事测了一下memcpy

7.总结

memcpy需要根据情况优化,如 平台,处理器,拷贝大小。

实现memcpy()函数及过程总结的更多相关文章

  1. memcpy函数的用法以及实现一个memcpy函数

    memcpy的用法 在项目中经常用到memcpy来实现内存的拷贝工作,如下代码片段 memcpy( pData, m_pSaveData_C, iSize * sizeof( unsigned sho ...

  2. 利用memcpy函数实现float到QByteArray的相互转化

    一.为什么要实现float到QByteArry之间的相互转化 在总线通讯过程中(例如串口通讯),总线上传输的是字节数组变量,即ByteArray型的变量,在Qt中即为QbyteArray型变量.总线发 ...

  3. memmove和memcpy函数的区别及实现

    一.memmove()和memcpy()函数和strcpy()函数的区别: (1)使用的类型不同,strcpy()函数只对字符串进行操作:memmove()和memcpy()函数对所有类型都适用,为内 ...

  4. C语言memcpy()函数和memmove()函数

    C语言memcpy()函数和memmove()函数 关于 memcpy() 函数,请先看链接. memcpy() 函数和 memmove() 函数的函数原型如下: void* memcpy(void ...

  5. memcpy函数用法

    memcpy函数用法 .分类: VC++ VC++ mfc matlab 2011-12-01 19:17 14538人阅读 评论(0) 收藏 举报 null 原型:extern void *memc ...

  6. C语言之memcpy函数

    昨天自己动手实现memcpy这个函数,用一个例程试了一下,结果正确,满心欢心,可是有些地方想不明白,于是百度了一下,结果自己写的函数简直无法直视. 觉得还是写个总结,以示教训. 先贴上我自己的函数: ...

  7. 【转】【C/C++】实现memcpy函数

    本文转自:http://my.oschina.net/renhc/blog/36345 面试中如问到memcpy的实现,那就要小心了,这里有陷阱. 先看下标准memcpy()的解释: ? 1 2 vo ...

  8. memcpy函数

    实现1:<高质量c++,c编程指南> void *mymemcpy(void *dst,const void *src,size_t num) { assert((dst!=NULL)&a ...

  9. memcpy函数的使用方法

    c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中. 1.函数原型 void *memcpy(void * ...

随机推荐

  1. es之java索引操作

    1.7.1: 创建索引 /** * 创建索引 * */ @Test public void createIndex(){ // 创建索引 CreateIndexResponse blog2 = cli ...

  2. CSS基础-background的那些属性

    background的那些属性 background:背景的意思常用的六个属性 1.background-color:背景颜色 2.background-image:背景图像 3.background ...

  3. 8 Django 模型层(2)

    知识预览 多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型 ...

  4. 《SQL Server 2012 T-SQL基础》读书笔记 - 10.可编程对象

    Chapter 10 Programmable Objects 声明和赋值一个变量: DECLARE @i AS INT; SET @i = 10; 变量可以让你暂时存一个值进去,然后之后再用,作用域 ...

  5. Longest Subarray(HDU6602+线段树)

    题意 要你找一个最长的区间使得区间内每一个数出现次数都大于等于K. 题解->https://blog.csdn.net/Ratina/article/details/97503663 #incl ...

  6. 从 Quora 的 187 个问题中学习机器学习和NLP

    从 Quora 的 187 个问题中学习机器学习和NLP 原创 2017年12月18日 20:41:19 作者:chen_h 微信号 & QQ:862251340 微信公众号:coderpai ...

  7. linux socket 缓存: core rmem_default rmem_max

    https://blog.csdn.net/penzchan/article/details/41682411

  8. Hibernate入门简介

    什么是Hibernate框架? Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接存取 ...

  9. 用Vue来实现音乐播放器(十七):歌手页右侧快速入口实现

    快速入口的列表是其实是之前处理的歌手的数据中的关于title的列表 shorcutList属性是计算属性   通过ret数组中的title计算到的 所以我们要在singer.vue组件中将数据传入到l ...

  10. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_09 序列化流_4_transient关键字_瞬态关键字

    不想被序列化的成员变量用 transient修饰 age加上static关键字 反序列化age就读取不到正确的值了