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. linux 文件相关常用命令

    文件或者目录操控命令 1,cd切换目录. 其中- 代表前一个目录 2,mkdir 新建目录. 加上-p参数可以递归创建多级目录 mkdir -p test1/test2/test3 3,rmdir删除 ...

  2. 在 iTerm2 终端使用 command + ;会弹出最近使用的命令列表

  3. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_08 Map集合_4_Map集合遍历键找值方式

    键找值的方式 增强for 增强for的简化方式

  4. python学习笔记(数据类型)

    python数据类型: int 类型 float 小数类型 string 字符串 布尔类型 a = True b = False 1.列表,也称数组或list或array.它的表达方式通过下标或索引或 ...

  5. Python 爬取淘宝商品数据挖掘分析实战

    Python 爬取淘宝商品数据挖掘分析实战 项目内容 本案例选择>> 商品类目:沙发: 数量:共100页  4400个商品: 筛选条件:天猫.销量从高到低.价格500元以上. 爬取淘宝商品 ...

  6. 伪造IP及获取客户端真实IP地址

    Fiddler支持自定义规则,可以实现对HTTP请求数据发送给Server前或HTTP应答数据发送给浏览器前进行修改.下面的例子将演示如何向所有HTTP请求数据中增加一个头.1)打开Fiddler,点 ...

  7. 我的常用的Linux命令

    环境:centos7 主要应用Linux命令是为了搭建环境,所以记录一下我的常用的Liunx命令 一.常用目录.文件操作命令 1.显示目录列表命令 ls       显示当前目录下的可见文件 ls - ...

  8. 【ABAP系列】SAP ABAP同时显示多个ALV的方法

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP同时显示多个AL ...

  9. unity编辑器Hierarchy添加图标

    效果 素材 using UnityEditor; using UnityEngine; using System.Collections.Generic; [InitializeOnLoad] cla ...

  10. 解决:”ssh-keygen 不是内部或外部命令“ 的问题

    相信大家在 码云生成/添加SSH公钥的过程中遇到一个比较常见的问题, 在cmd,命令行输入 ssh-keygen -t rsa -C "xxxxx@xxxxx.com" ; xxx ...