DPDK内存(二)内存申请操作
EAL提供了一个malloc API用于申请任意大小内存。
这个API的目的是提供类似malloc的功能,以允许从hugepage中分配内存并方便应用程序移植。
通常,这些类型的分配操作不应该在数据面处理中进行,因为他们比基于池的分配慢,并且在分配和释放路径中使用了锁操作。但是,他们可以在配置代码中使用。
1.Cookies
当CONFIG_RTE_MALLOC_DEBUG开启时,分配的内存包括保护字段,这个字段用于帮助识别缓冲区溢出。
2.对齐和NUMA限制
接口rte_malloc()传入一个对齐参数,该参数用于请求在该值的倍数上对齐的内存区域(这个值必须是2的幂次)。
在支持NUMA的系统上,对rte_malloc()接口调用将返回在调用函数的Core所在的插槽上分配的内存。DPDK还提供了另一组API,以允许在指定NUMA插槽上直接显式分配内存,或者分配另一个NUAM插槽上的内存。
3.用例
这个API旨在由初始化时需要类似malloc功能的应用程序调用。
需要在运行时分配/释放数据,在应用程序的快速路径中,应该使用内存池库。
4.内部实现
4.1数据结构
Malloc库中内部使用两种数据结构类型:
struct malloc_heap:用于在每个插槽上跟踪可用内存空间
struct malloc_elem:库内部分配和释放空间跟踪的基本要素
4.1.1malloc_heap
数据结构malloc_heap用于管理每个插槽上的可用内存空间。在内部,每个NUMA节点有一个堆结构,这允许我们根据此线程运行的NUMA节点为线程分配内存。虽然这并不能保证在NUMA节点上使用内存,但是它并不比内存总是在固定或随机节点上的方案更糟。
堆结构及其关键字段和功能描述如下:
lock:需要锁来同步对堆结构的访问。假定使用链表来跟踪堆中的可用空间,我们需要一个锁
来防止多个线程同时处理该链表。
free_head:指向这个malloc堆的空闲结点链表中的第一个元素。
4.1.2malloc_elem
数据结构malloc_elem用作各种内存块的通用头结构。 它以三种不同的方式使用,如上图所示:
1.作为一个释放/申请内存的头部,正常使用
2.作为内存块内部填充头
3.作为内存结尾标记
结构中重要的字段和使用方法如下所述:
1.heap:这个指针指向了该内存块从哪个堆申请。它被用于正常的内存块,当他们被释放时,将新释放的块添加到堆的空闲列表中。
2.prev:这个指针用于指向紧跟着当前memseg的头元素。当释放一个内存块时,该指针用于引用上一个内存块,检查上一个块是否也是空闲。如果空闲,则将两个空闲块合并成一个大块。
3.next_free:这个指针用于将空闲块列表连接在一起。它用于正常的内存块,在malloc() 接口中用于找到一个合适的空闲块申请出来,在free() 函数中用于将内存块添加到空闲链表。
4.state:该字段可以有三个可能值:FREE, BUSY 或 PAD。前两个是指示正常内存块的分配状态,后者用于指示元素结构是在块开始填充结束时的虚拟结构,即,由于对齐限制,块内的数据开始的地方不在块本身的开始处。在这种情况下,pad头用于定位块的实际malloc元素头。对于结尾的结构,这个字段总是BUSY,它确保没有元素在释放之后搜索超过memseg的结尾以供其它块合并到更大的空闲块。
5.pad:这个字段为块开始处的填充长度。在正常块头部情况下,它被添加到头结构的结尾,以给出数据区的开始地址,即在malloc上传回的地址。在填充虚拟头部时,存储相同的值,并从虚拟头部的地址中减去实际块头部的地址。
6.size:数据块的大小,包括头部本身。对于结尾结构,这个大小需要指定为0,虽然从未使用。对于正在释放的正常内存块,使用此大小值替代 “next” 指针,以标识下一个块的存储位置,在FREE情况下,可以合并两个空闲块。
4.2内存申请
在EAL初始化时,所有memseg都将作为malloc堆的一部分进行设置。这个设置包括在BUSY状态结束时放置一个虚拟结构,如果启用了CONFIG_RTE_MALLOC_DEBUG,它可能包含一个哨兵值,并在开始时为每个memseg指定一个适当的元素头。然后将FREE元素添加到malloc堆的空闲链表中。
当应用程序调用类似malloc功能的函数时,malloc函数将首先为调用线程索引lcore_config结构,并确定该线程的NUMA 节点。NUMA 节点将作为参数传给heap_alloc()函数,用于索引malloc_heap 结构数组。参与索引参数还有大小、类型、对齐方式和边界参数。
函数heap_alloc()将扫描堆的空闲链表,尝试找到一个适用于所请求的大小、对齐方式和边界约束的内存块。
当已经识别出合适的空闲元素时,将计算要返回给用户的指针。紧跟在该指针之前的内存的高速缓存行填充了一个malloc_elem头部。由于对齐和边界约束,在元素的开头和结尾可能会有空闲的空间,这将导致已下行为:
1.检查尾随空间。如果尾部空间足够大,例如 > 128 字节,那么空闲元素将被分割。否则,仅仅忽略它(浪费空间)。
2.检查元素开始处的空间。如果起始处的空间很小, <=128 字节,那么使用填充头,这部分空间被浪费。但是,如果空间很大,那么空闲元素将被分割。
从现有元素的末尾分配内存的优点是不需要调整空闲链表,空闲链表中现有元素仅调整大小指针,并且后面的元素使用 “prev” 指针重定向到新创建的元素位置。
4.3内存释放
要释放内存,将指向数据区开始的指针传递给free函数。从该指针中减去malloc_elem结构的大小,以获得内存块元素头部。如果这个头部类型是PAD,那么进一步减去pad长度,以获得整个块的正确元素头。
从这个元素头中,我们获得指向块所分配的堆的指针及必须被释放的位置,以及指向前一个元素的指针,并且通过size 字段,可以计算下一个元素的指针。 这意味着我们永远不会有两个相邻的FREE 内存块,因为他们总是会被合并成一个大的块。
DPDK内存(二)内存申请操作相关推荐
- DPDK 大页内存实现(二十二)
上一篇文件介绍了linux内存管理以及大页内存的原理,有了原理的支撑,接下里分析dpdk大页内存源码就轻松了,才不会云里雾里不知道在说啥.所谓的dpdk大页内存的实现,说白了就是dpdk自己实现了一套 ...
- DPDK 大页内存原理(二十一)
在分析dpdk大页内存的源码之前,有必要对linux内存管理的原理以及大页内存的原理有个了解,缺少这些底层基础知识,分析dpdk大页内存的源码将举步维艰.这篇文章详细介绍下linux内存管理以及大页内 ...
- Netty 内存池(二)内存申请流程
Netty 内存池(二)内存申请流程 上期带大家了解了一下Netty内存池都有哪些重要的对象,以及这些对象的作用是什么,本期就带大家分析一下线程是如何申请一块内存的.本期由于涉及到了很多变量和位运算, ...
- dpdk内存管理——内存初始化
*说明:本系列博文源代码均来自dpdk17.02* 1.1内存初始化 1.1.1 hugepage技术 hugepage(2M/1G..)相对于普通的page(4K)来说有几个特点: (1) huge ...
- dpdk代码分析——内存初始化
一. 前言 dpdk 是 intel 开发的x86芯片上用于高性能网络处理的基础库,业内比较常用的模式是linux-app模式,即利用该基础库,在用户层空间做数据包处理,有了这个基础库,可以方便地在写 ...
- linux申请大块内存,linux 内存看一篇就够了(多图)
image 正文 0 内存模块 image 1 linux内存总体布局:内存分成用户态和内核态 4G进程地址空间解析 image image 内核地址空间 image image 进程地址空间 ima ...
- C语言知识点 -- 动态内存管理、文件操作
C语言知识点 – 动态内存管理.文件操作 文章目录 C语言知识点 -- 动态内存管理.文件操作 一.动态内存管理 1.malloc 2.free 3.calloc 4.realloc 二.文件操作 1 ...
- 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 缓存策略 | LruCache 内存缓存 | LruCache 常用操作 | 工具类代码 )
文章目录 一.Bitmap 内存缓存策略 二.LruCache 内存缓存 三.LruCache 常用操作 四.LruCache 工具类 五.源码及资源下载 官方参考 : Google 官方提供的 内存 ...
- Spark(二): 内存管理
2019独角兽企业重金招聘Python工程师标准>>> Spark 作为一个以擅长内存计算为优势的计算引擎,内存管理方案是其非常重要的模块: Spark的内存可以大体归为两类:exe ...
- java 排序 内存_Java内存模型(二)——重排序
一.重排序 重排序是指为了提高程序的执行效率,编译器和处理器常常会对语句的执行顺序或者指令的执行顺序进行重排. 编译器优化的重排序:编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序. ...
最新文章
- qt客户端连接服务器不响应,qt判断tcp客户端是否连接服务器
- 刷卡读取信息自动录入表格_人事自动化管理系统.xls
- 博客园设置访问统计功能-by beanmoon
- Vue打包并发布项目
- 高通利用DMCA通知迫使GitHub关闭100+代码库
- 卡盟销售官网源码php,卡盟整站程序源码 php版
- 如果把钢铁侠中的贾维斯系统换成现在的人工智能会怎么样?
- 趣头条面试题:ThreadLocal是什么?怎么用?为什么用它?有什么缺点
- typecho图片插件_typecho插件:HighSlide文章弹窗相册插件
- Vue中router-link路由跳转以及传参方式
- 如何判断网线连接状态
- python pyecharts生成图表
- android 监控行为,一种针对Android系统App行为的监控方法
- Android中DialogFragment自动弹出输入法
- windows 设置设置程序的起始位置
- Wireshark基本使用方法
- 51单片机实现BMP280气压计海拔高度解析(附代码)
- anaconda初体验
- Python中range()函数的用法
- 微生物组学测序十大错误认知