memcpy函数优化及DMA对比

article/2025/9/16 16:22:16

一、背景与目的

优化算法结构,提高芯片的使用效率,挖掘芯片的潜在能力,对提高产品质量,降低产品成本有着重要意义,在性能受限的嵌入式设备更加重要。
在使用C语言编程时,我们常用memcpy来复制内存数据,最简单的memcpy功能实现如下:

void *memcpy(void *desc,const void * src,size_t size)
{if((desc == NULL) && (src == NULL)){return NULL;}unsigned char desc1 = (unsigned char)desc;unsigned char src1 = (unsigned char)src;while(size-- >0){*desc1 = *src1;desc1++;src1++;}return desc;
}

这是一个标准通用的memcpy函数的实现,满足memcpy的功能,但性能非常低,因为while每一次循环只能复制一个字节。
如果要进一步的优化,就需要用到更多的知识,例如CPU位宽、数据对齐、汇编指令等等,学过计算机原理应该知道CPU字长、寄存器位宽等概念。
现在常见的CPU通常为32/64位,今天我们以32位Arm Cortex -M4来讲解。

二、数据对齐

32位CPU字长为32Bit,即它的每个通用寄存器包含32个位,占4个字节,一个内存访问周期可以完成4个字节的读写。
如果按照标准memcpy函数的实现,每次while循环只能复制1个字节,会浪费大量的内存访问周期。那我们能否按照32位CPU位宽,即4个字节为单位进行内存复制呢?CPU从内存取数据的过程,对齐存放的数据可加快CPU处理的速度,因为在同一个时钟周期内,CPU访问的数据总是按32位对齐访问的。(一些CPU能够非对齐访问,如Arm Cortex -M4支持半字的非对齐访问,和双字的字节对齐访问Arm Cortex -M4内存对齐问题)
例如:

  1. CPU寄存器从内存0x20000001开始取32位数据需要两次访问内存:第一次取3字节0x20000001~0x20000003,第二次取1字节0x20000004。
  2. CPU寄存器从内存0x20000002开始取32位数据需要两次访问内存:第一次取3字节0x20000002~0x20000003,第二次取1字节0x20000004~0x20000005。
  3. CPU寄存器从内存0x20000004开始取32位数据需要一次访问内存:一次取4字节0x20000004~0x20000007。
    在这里插入图片描述

参考上图,如果需要按对齐方式将0x20000001到0x2000002C中总共44字节的数据拷贝到0x20000041、0x20000082,0x200000C3,0x20000104这几个目标位置,最少的复制过程包括哪些步骤呢?

  • 0x20000001拷贝到0x20000041:四字节对齐。先按字节复制前3个字符,需要循环3次,再按4字节对齐复制0x20000004到0x2000002B之间的数据,共需要循环10次,最后一个字节复制1次,共计14次内存访问。

  • 0x20000001拷贝到0x20000082:因为源和目标无法同时对齐,只能按照字节复制,需要访问内存44次。

  • 0x20000001拷贝到0x200000C3:两字节对齐。先按字节复制前1个字符,需要循环1次,再按2字节对齐复制0x20000002到0x2000002B之间的数据,共需要循环21次,最后一个字节复制1次,共计23次内存访问。

  • 0x20000001拷贝到0x20000100:因为源和目标无法同时对齐,只能按照字节复制,需要访问内存44次。

通过上述分析,我们发现:

  1. 32位CPU中,4字节对齐的数据拷贝能够对齐,性能提升接近4倍;2字节对齐的数据拷贝能够对齐,性能提升接近2倍。

  2. 32位CPU中,源地址和目标地址对4取模的结果一致时为,4字节对齐;源地址和目标地址对2取模的结果一致时为,2字节对齐。

void* memcpy1(void* dst, const void* src, size_t len) {int* d = (int*) dst;const int* s = (const int*) src;for (size_t i=0; i < len; i += 4) {*d++ = *s++;}return d;
}

例如以上代码示例,按int的字长进行拷贝以提高效率。(使用时dst和src都需要4字节对齐,len需要被4整除)

三、指令流水线

指令流水线的作用是将一条指令分割成多个步骤,并由不同的部件顺序完成,
在同一时刻,每个部件可以同时执行多个指令的不同步骤,尽可能保证每个时钟周期都能输出一条指令结果。利用CPU流水线处理的指令的能力,解除数据依赖,(原理是前一条指令在译码,后一条语句在取指,充分压榨CPU处理器)。
在这里插入图片描述

void *memcpy2(void *desc,const void * src,size_t size)
{if((desc == NULL) && (src == NULL)){return NULL;}unsigned char desc1 = (unsigned char)desc;unsigned char src1 = (unsigned char)src;unsigned char count = size/4;while(count -- >0){*desc1++ = *src1++;*desc1++ = *src1++;*desc1++ = *src1++;*desc1++ = *src1++;}count = size%4; while(count --){*desc1++ = *src1++;}return desc;
}

例如以上代码,将拷贝循环展开的跳转次数大幅减少,跳转次数最多减少到原来的1/4。

四、汇编版本优化

  1. 利用Arm的汇编指令集中的 LDMIA STMIA指令,通过这两条指令,一次就可以读取/写入多个字节(一次最大读取40字节),极大的加速了拷贝过程。rt_memcpy Cortex-M 汇编加速版
  2. 加载读取的汇编流水线优化
    加载和写入流水线细节优化

四、DMA

DMA:全称Direct Memory Access(直接存储器访问),把一个地址空间的值“复制”到另一个地址空间,使用DMA传输方式无需CPU直接控制传输,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,使得CPU的效率大大提高。
本文使用STM32L4R9在主频120M的情况下进行对比实验。其DMA可以配置为传输的类型大小(字节、半字、字)。传输长度32K。

五、对比测试及结果

在这里插入图片描述
通过上述测试结果,我们发现:

  1. 按字节、半字、字传输,其效率也随单次拷贝字宽成倍增加。
  2. 汇编的memcpy效率比DMA32也要高2.65倍(后续研究了一下,应该时LDM指令对AHB总线的突发访问长度的配置了较大的数,大幅提高了效率比DMA的还要高。)

🎉🎉🎉完结撒花🎉🎉🎉

http://chatgpt.dhexx.cn/article/nUbO7iFA.shtml

相关文章

memcpy函数的介绍以及实现

一、memcpy函数的介绍 memcpy函数在C语言的作用是将第一个变量a中的前num个字节的变量替换成第二个变量b的前num个字节 memcpy - C Reference (cplusplus.com) 二、memcpy函数的模拟实现 我的思路是这样的&#xff1a;首先&#xff0c;要判断这两个传来的地址是否是空指针&…

Linux下的memcpy函数

之前写过一篇关于 memcpy函数面试的文章 几个简单的笔试题 里面的代码使用的是char指针来实现&#xff0c;今天我们来看看Linux下面的memcpy 函数&#xff0c;它的实现上还是有一些巧妙的。 void * memcpy(void * dest, const void *src, size_t n) {if (!(((unsigned long) de…

内存操作函数:memcpy函数,memove函数

目录: 1.memcpy函数(内存拷贝)(1)memcpy函数的说明(2)memcpy的使用a.代码b.结果 (3)memcpy的模拟实现a.代码b.结果 2.memmove函数(1)memmove函数的说明(2)内存重叠问题a.分析b.代码说明 (3)内存重叠问题的解决分析(4)memmove的使用(5)模拟实现memmove 1.memcpy函数(内存拷贝) …

memcpy函数和memmove函数

memcpy函数和memmove函数 本篇博客只要涉及到memcpy函数与memmove函数的使用和模拟 文章目录 memcpy函数和memmove函数一、memcpy函数1.1函数的定义1.2memcpy函数使用1.3memcpy函数模拟实现 二、memmove函数2.1memmove函数定义2.2memmove模拟思路 总结 一、memcpy函数 1.1函数…

memcpy函数底层实现

memcpy函数底层源码实现 destin目标地址&#xff0c;source为源内存地址&#xff0c;n为拷贝的字节数 void *memcpy(void *destin, void *source, unsigned n);在实现memcpy的时候注意源地址和目的地址是否重叠&#xff0c;当源地址的尾部与目的地址头部重叠时&#xff0c;要…

memcpy函数及模拟

1memcpy函数的参数和返回值 1.1参数 目的地&#xff08;destination&#xff09; 指向要在其中复制内容的目标数组的指针&#xff0c;类型转换为 void* 类型的指针。 源&#xff08;source&#xff09; 指向要复制的数据源的指针&#xff0c;类型转换为 const void* 类型的指针…

简单讲解memcpy函数并且实现memcpy函数

函数声明&#xff1a;void *memcpy(void*dest, const void *src, size_t n);//n代表的是字节 使用方法&#xff1a;由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。 返回值&#xff1a;在未开始复制之前&#xff0c;dest指向的地址。 …

C语言memcpy函数和memmove函数

memcpy函数和memmove函数都是C语言的库函数&#xff0c;作用都是从一个空间copy一定长度的内容到另一个空间&#xff0c;不同的是memcpy只是单纯的拷贝&#xff0c;当两个空间发生局部重叠时无法保证拷贝的正确&#xff08;正不正确取决于编译器&#xff09;&#xff0c;而memm…

memcpy函数用法

各位读者朋友们&#xff0c;由于更新blog不易&#xff0c;如果觉得这篇blog对你有用的话&#xff0c;麻烦关注&#xff0c;点赞&#xff0c;收藏一下哈&#xff0c;十分感谢。 1、简介 memcpy 函数用于把资源内存&#xff08;src所指向的内存区域&#xff09; 拷贝到目标内存…

【C库函数】memcpy函数详解

目录 memcpy 函数原型 参数讲解 返回值讲解 函数讲解&#xff08;三个注意点&#xff09; memcpy 拷贝内存块到目标空间 函数原型 void *memcpy( void *dest, const void *src, size_t count ); 参数讲解 参数destsrccount解析目标空间地址要拷贝内容空间源地址拷贝内容…

C语言——内存操作函数(memcpy、memmove、memcmp、memset)

文章目录 &#x1f4d8;前言&#x1f4d7; 一、memcpy&#xff08;内存拷贝&#xff09;&#x1f4d6; 1. 函数说明&#x1f4d6; 2. 模拟实现&#x1f4a1; 3. 运行图示: &#x1f4d7;二、memmove&#x1f4d6; 1. 函数说明&#x1f4d6; 2. 模拟实现&#x1f4a1; 3. 运行图…

memcpy函数详解 看这一篇就够了-C语言(函数讲解、 使用用法举例、作用)

memcpy()函数用于&#xff1a;复制内存块 函数介绍 函数声明&#xff1a;void * memcpy ( void * destination, const void * source, size_t num ); 参数 目的地&#xff1a;指向要在其中复制内容的目标数组的指针&#xff0c;类型转换为 void* 类型的指针。 源&#xff1a;指…

智慧校园信息化管理平台技术方案

1.2总体架构设计 智慧校园平台是以学校现有网络为基础&#xff0c;以服务于全校师生的教学、科研、生活为目的&#xff0c;建立在学校数据中心平台之上&#xff0c;涵盖了学校的学校管理、学生管理、教学管理、班级管理、家校共育、教务管理等全方位的管理信息平台与信息服务平…

县域教育信息化优质均衡建设解决方案

项目概述 “人才决定未来&#xff0c;教育成就梦想”。我国一直坚持不懈推进教育信息化&#xff0c;努力以信息化为手段扩大优质教育资源覆盖面。我国规划将通过教育信息化&#xff0c;逐步缩小区域、城乡数字差距&#xff0c;大力促进教育公平&#xff0c;让亿万孩子同在蓝天…

XXX高校数字化校园数据中心建设方案

目录 一、 项目概述 4 1.1建设背景 4 1.2建设目标 5 1.3建设原则 6 1.4云平台技术打造大数据与高性能优势 7 二、 需求分析 9 2.1现状分析 9 2.2总体建设 9 2.2.1XXX高校校园云平台需求 10 2.2.2大数据分析需求 10 2.2.3高性能需求 12 三、 数据中心总体规划 14 四…

智慧教育信息化建设解决方案

建设思路及解决方案 以数据整合、应用融合、服务聚合为目标&#xff0c;充分利用已有的成果&#xff0c;联接全校物联感知设备、构筑智能化安防体系&#xff0c;打造泛在化的学习环境、实现一体化的运维管控&#xff0c;最终形成智慧环境、智慧管理、智慧服务、智慧教学、智慧资…

信息化建设规划_职业院校教育信息化建设发展规划编制培训班圆满落幕!

9月24日至25日&#xff0c;由中国高等教育培训中心主办的职业院校教育信息化建设发展规划编制培训班&#xff0c;在重庆滨乐宝轩酒店盛大举行。会上&#xff0c;来自全国的教育专家、学者齐聚一堂&#xff0c;共同探讨智慧校园建设实现路径&#xff0c;面向与会的百余名教育工作…

如何建设教育信息化评价指标体系?

原创 CERNET 中国教育网络 2020-09-16 在教育信息化生态系统中&#xff0c;有三大推动力量&#xff1a;教育信息化评价指标体系制定、评估工作开展和评估建模分析&#xff0c;这三者相互依赖、相互影响。 01高校信息化建设的现状与问题 自从教育部发布《教育信息化2.0行动计…

某企业运营(集团)有限公司信息化建设规划方案

目录 1. 单位信息化建设现状分析 1.1 网络性能风险 1.2 管理功能风险 1.3 网络安全风险 1.4 数据安全风险 1.5 访问身份识别风险 1.6 信息化支撑环境风险 2. 需求分析 2.1 网络及管理需求分析 2.2 网络安全需求分析 2.3 …