一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

基于CMA实现支持大内存连续分配的内存管理方法及系统与流程

2021-10-24 06:41:00 来源:中国专利 TAG:内存管理 分配 内存 连续 支持

基于cma实现支持大内存连续分配的内存管理方法及系统
技术领域
1.本发明涉及计算机操作系统领域,具体涉及一种基于cma实现支持大内存连续分配的内存管理方法及系统。


背景技术:

2.加速器是提高计算机性能的重要手段之一。典型的异构加速器主要分为两种:片外加速器和片上加速器。片外加速器,如显卡等,是目前较为常用的加速器,通过pci总线从cpu获取数据进行计算。片上加速器则支持与cpu共享内存,以申威芯片为例,它具有4个较大的核用于管理计算机的运行,256个较小的核则用于加速计算。目前在全球超级计算机top500榜单中排名第一的富岳超级计算机采用的也是类似的结构。
3.不论片外加速器还是片上加速器,如何快速获取数据都是一直以来的性能瓶颈,为了缓解这个问题,cpu被要求更有效地组织好内存数据,以便加速器访问。一个解决办法是将加速器所需的数据存储在连续的内存地址上。当前linux已经可以利用dma分配一些连续的页面,但对于加速器来说,dma的限制在于可一次性分配的内存太少,难以支持大规模应用的内存需求,并且多次dma操作也大大增加了时间成本。
4.为了满足用户日益增加的内存需求,一些计算机选择将多块内存组合起来,以形成一个更大的内存空间,这就导致了同一块内存在cpu和加速器的视角下可能拥有不同的地址。此外,一些片上加速器没有虚拟内存机制,应用无法通过连续的逻辑地址进行访存,这也是数据获取速度的一个制约因素。
5.cma是内存管理子系统中的一个模块,负责物理地址连续的内存分配。其内存分配区域称为cma area。当前驱动没有分配使用的时候,这些cma area的内存可以被内核的其他模块使用,而当驱动分配cma内存后,那些被其他模块使用的内存需要吐出来,形成物理地址连续的大块内存,给具体的驱动来使用。一般系统会在启动过程中,从整个memory中配置一段连续内存用于cma,其他模块可以通过cma的接口api进行连续内存分配。cma的主要功能包括:解析dts或者命令行中的参数,确定cma area;提供cma_alloc和cma_release两个接口用于分配和释放cma pages;记录和跟踪cma area中各个pages的状态;调用伙伴系统接口,进行真正的内存分配等。cma被集成到dma子系统,设备驱动不必直接调用cma api,因为它是在页和页帧编号(起始页框号pfn)上操作而无关总线地址和内核映射,能保证系统分配连续内存的成功率。此外,cma解决了内存浪费的问题,其保留的内存可以由伙伴系统分配,当真正需要此连续内存时,可以将由伙伴系统分配的内存迁移到其他地方。但cma在内存迁移会带来性能损耗,在内存紧张时,cpu占用率增加尤为明显。linux内核为了尽量减少空间的浪费,减少申请释放内存的消耗时间,采用基于伙伴算法的存储分配机制。伙伴系统算法把内存中的所有页框按照大小分成10组不同大小的页块,每块分别包含1,2,4,
……
,512个页框。每种不同的页块都通过一个free

area

struct结构体来管理。系统将10个free

area

struct结构体组成一个free

area[]数组。在free

area

struct包含指向空闲页块链表的指针。当向内存请求分配一定数目的页框时,若所请求的页框数目不是2的
幂次方,则按稍大于此数目的2的幂次方在页块链表中查找空闲页块,如果对应的页块链表中没有空闲页块,则在更大的页块链表中查找。当分配的页块中有多余的页框时,伙伴系统将根据多余的页框大小插入到对应的空闲页块链表中。向伙伴系统释放页框时,伙伴系统会将页框插入到对应的页框链表中,并且检查新插入的页框能否和原有的页块组合构成一个更大的页块,如果两个块的大小相同且这两个块的物理地址连续,则合并成一个新页块加入到对应的页块链表中,并迭代此过程直到不能合并为止,这样可以极大限度地减少内存的外部碎片。
[0006]
综上所述,现有分配机制无法提供连续的大片内存空间(物理及虚拟),并且易产生较多的内存碎片,同时linux对合并分散内存所采取的内存迁移机制时间代价较大。


技术实现要素:

[0007]
本发明要解决的技术问题:针对现有技术的上述问题,提供一种基于cma实现支持大内存连续分配的内存管理方法及系统,本发明旨在针对加速器的结构特点,通过优化内存管理机制,实现面向加速器的大内存连续页面分配,减少内存碎片及取数延迟。
[0008]
为了解决上述技术问题,本发明采用的技术方案为:
[0009]
一种基于cma实现支持大内存连续分配的内存管理方法,包括:
[0010]
1)面向加速器建立全局位图all_bitmap;
[0011]
2)将连续内存分配模块cma中各个分散的cma区域zone 1~zone n的位图bitmap映射到全局位图all_bitmap中,将全局位图all_bitmap作为面向加速器进行大内存连续分配的节点node0,形成内存、cma区域、节点node0三者构成的内存页

cma区域

节点层级组织结构以组织全局可连续访问的连续物理页面;
[0012]
3)当需要分配连续物理页面时,基于全局位图all_bitmap分配连续物理页面,且在完成分配后更新全局位图all_bitmap中的连续物理页面的分配状态;当需要释放连续物理页面时,则释放连续物理页面,并更新被释放连续物理页面在全局位图all_bitmap中状态为未分配状态以供备用。
[0013]
可选地,步骤3)之前还包括为加速器预先预取指定大小的连续物理页面到内存缓冲池的步骤,步骤3)中基于全局位图all_bitmap分配连续物理页面是指基于全局位图all_bitmap从预取到内存缓冲池中分配连续物理页面。
[0014]
可选地,步骤3)中分配连续物理页面的步骤包括:
[0015]
接收到用户对分配连续物理页面接口cmt_malloc的第一调用请求,所述第一调用请求中包含的所需页面数count;
[0016]
通过内存分配器hoard接收第一调用请求,转换并发起对内存分配器hoard中的分配连续物理页面接口mt_malloc的第二调用请求以进入底层分配流程;
[0017]
通过dma模块接收第二调用请求,转换并发起对dma模块中的分配连续物理页面接口cont_malloc的第三调用请求以进入连续内存分配流程;
[0018]
通过连续内存分配模块cma接收第三调用请求,转换并执行连续内存分配模块cma中的连续物理页面分配函数_cont_malloc:所述连续物理页面分配函数_cont_malloc首先通过预设的起始页框号查找函数find_base_pfn查找全局位图all_bitmap获取空闲物理页面的起始页框号pfn,然后根据查找得到的起始页框号pfn和所需页面数count向用于分配
物理页面的伙伴系统发出分配物理页面请求以通过伙伴系统执行具体的物理页面分配。
[0019]
可选地,所述预设的起始页框号查找函数find_base_pfn查找全局位图all_bitmap获取空闲物理页面的起始页框号pfn的步骤包括:
[0020]
声明临时区域结构cma,从用于记录cma区域zone1~zone
n
的cma_area数组中的任一元素复制通用参数至临时区域结构cma;
[0021]
遍历cma_area数组,累加每个元素对应的位图大小,将每个元素对应的位图大小求和得到全局位图all_bitmap的大小bitmap_maxno;
[0022]
根据分配连续物理页面请求的所需页面数count计算所需位图大小bitmap_count;
[0023]
判断所需位图大小bitmap_count小于全局位图all_bitmap的大小bitmap_maxno是否成立,若成立则跳转执行下一步,否则返回空,结束并退出;
[0024]
将cma_area数组上锁;
[0025]
找到全局位图all_bitmap中一段足够大的连续空间的起始下标bitmap_no;
[0026]
将cma_area数组解锁;
[0027]
判断连续空间的起始下标bitmap_no在全局位图all_bitmap范围内是否成立,若成立则跳转执行下一步,否则返回空,结束并退出;
[0028]
找到连续空间的起始下标bitmap_no对应的连续内存地址分配区域zone
i
,计算对应的空闲物理页面的起始页框号pfn,将空闲物理页面的起始页框号pfn反馈给连续物理页面分配函数_cont_malloc。
[0029]
可选地,所述伙伴系统执行具体的物理页面分配的步骤包括:
[0030]
重新映射全局位图all_bitmap;
[0031]
确定空闲物理页面的起始页框号pfn对应的连续内存地址分配区域zone
i

[0032]
判断连续内存地址分配区域zone
i
是否已经足够分配,若连续内存地址分配区域zone
i
足够分配,则从连续内存地址分配区域zone
i
中为调用请求执行内存分配并退出;否则,跳转执行下一步;
[0033]
首先分配连续内存地址分配区域zone
i
中可分配的尾部空间,然后分配相邻的下一个空闲的连续内存地址分配区域zone
i 1
;判断是否为调用请求分配到足够空间,如果已经分配到足够空间,则结束并退出,否则,将相邻的下一个空闲的连续内存地址分配区域zone
i 1
作为新的连续内存地址分配区域zone
i
,跳转执行步骤。
[0034]
可选地,步骤3)中则释放连续物理页面的步骤包括:
[0035]
接收到用户对释放连续物理页面接口cmt_free的第四调用请求;
[0036]
通过内存释放器hoard接收第四调用请求,转换并发起对内存释放器hoard中的释放连续物理页面接口mt_free的第五调用请求以进入底层释放流程;
[0037]
通过dma模块接收第五调用请求,转换并发起对dma模块中的释放连续物理页面接口cont_free的第六调用请求以进入连续内存释放流程;
[0038]
通过连续内存释放模块cma接收第六调用请求,转换并执行连续内存释放模块cma中的连续物理页面释放函数_cont_free:所述连续物理页面释放函数_cont_free向用于释放物理页面的伙伴系统发出释放物理页面请求以通过伙伴系统执行具体的物理页面释放。
[0039]
可选地,步骤3)之前还包括修改内存释放器hoard,使得系统同时兼容分配连续物
理页面接口cmt_malloc、原有分配连续物理页面接口malloc,释放连续物理页面接口cmt_free、原有释放连续物理页面接口free的步骤。
[0040]
可选地,所述修改内存释放器hoard的步骤包括:针对修改内存释放器hoard的底层结构实现部分源代码目录heap

layers下函数封装目录wrappers下,首先将所有函数封装文件中的函数暴露出的所有函数名加指定前缀cmt,以免与系统函数库libc中的系统函数冲突;然后将钩子函数封装文件中所有的钩子函数的返回值改为0以避免钩子函数hook调用系统函数库libc中的系统函数,使得内存释放器hoard中的内存、释放相关函数与系统函数库libc中的系统函数相互隔离,通过系统函数库libc中的系统函数响应原有分配连续物理页面接口malloc以及原有释放连续物理页面接口free,通过修改内存释放器hoard响应分配连续物理页面接口cmt_malloc以及释放连续物理页面接口cmt_free。
[0041]
此外,本发明还提供一种基于cma实现支持大内存连续分配的内存管理系统,包括相互连接的微处理器、内存模块以及加速器,该微处理器被编程或配置以执行所述基于cma实现支持大内存连续分配的内存管理方法的步骤。
[0042]
此外,本发明还提供一种计算机可读存储介质,该计算机可读存储介质中存储有被编程或配置以执行所述基于cma实现支持大内存连续分配的内存管理方法的计算机程序。
[0043]
和现有技术相比,本发明具有下述优点:
[0044]
1、本发明基于cma机制将分散的物理地址统一管理起来。本发明基于cma机制将内存以内存页

cma区域

节点(page

zone

node)的层级结构组织起来,形成可连续访问的内存空间,在此基础上可以实现将连续物理内存与连续虚拟内存的映射的操作。
[0045]
2、本发明依靠全局位图all_bitmap可实现准确分配内存,减少内存碎片。用全局位图代all_bitmap替每个cma area的本地位图,实现逻辑上的内存连续,以便更清晰地判断何处有足够分配的空闲空间,且消除两次分配间的外部碎片。
附图说明
[0046]
图1为本发明实施例方法的基本流程示意图。
[0047]
图2为本发明实施例中的内存页

cma区域

节点层级组织结构示意图。
[0048]
图3为本发明实施例中分配连续物理页面的执行过程示意图。
[0049]
图4为本发明实施例中函数find_base_pfn的流程图。
[0050]
图5为本发明实施例中函数_cont_malloc调用伙伴系统执行的分配流程图。
[0051]
图6为现有分配连续物理页面方法的执行过程示意图。
[0052]
图7为本发明实施例方法分配连续物理页面方法的执行过程示意图。
[0053]
图8为本发明实施例中释放连续物理页面的执行过程示意图。
具体实施方式
[0054]
参见图1,本实施例基于cma实现支持大内存连续分配的内存管理方法包括:
[0055]
1)面向加速器建立全局位图all_bitmap;
[0056]
2)将连续内存分配模块cma中各个分散的cma区域zone 1~zone n的位图bitmap映射到全局位图all_bitmap中,将全局位图all_bitmap作为面向加速器进行大内存连续分
配的节点node0,形成内存、cma区域、节点node0三者构成的内存页

cma区域

节点层级组织结构以组织全局可连续访问的连续物理页面,如图2所示;
[0057]
3)当需要分配连续物理页面时,基于全局位图all_bitmap分配连续物理页面,且在完成分配后更新全局位图all_bitmap中的连续物理页面的分配状态;当需要释放连续物理页面时,则释放连续物理页面,并更新被释放连续物理页面在全局位图all_bitmap中状态为未分配状态以供备用。
[0058]
本实施例中,步骤3)之前还包括为加速器预先预取指定大小的连续物理页面到内存缓冲池的步骤,步骤3)中基于全局位图all_bitmap分配连续物理页面是指基于全局位图all_bitmap从预取到内存缓冲池中分配连续物理页面。通过上述预取(预分配),可有效减少访存次数。伙伴系统必须分配2的幂个页面(页面的大小并不固定,这里仍旧默认为4k),而位图仅将所需页数对应的位置1,所以会出现位图显示空白的空间却无法分配的问题,因此并不能很好地支持任意大小的内存分配。在原本的位图映射版本中,遇到页面busy,无法正常分配的情况时,会自动查找下一个相邻的cma_area,但这样依然相当于有一定的内存碎片。针对这个问题,本实施例方法中增加了物理内存预分配的操作,即在加载设备的时候,就将预留的cma物理空间全部分配出去,然后对位图单独执行分配和释放的操作,也就是不再等到申请时才分配物理内存,而是在申请时直接做物理内存与虚拟内存的映射。由于不用在每次申请的时候都进行一遍物理内存的分配工作,这个版本在时间性能上表现很好。对于没有虚拟内存的片上加速器,这一优化相当于只改变了提供给加速器的地址范围,后续不再需要频繁分配/释放,而对于其他加速器,本实施例方法仍然支持在虚拟内存中划分出一块连续空间,只不过用改变映射范围的方式代替了访存,而且通过构建内存缓冲池,减少内存映射次数,,通过一次性为应用预留大块内存的方式,减少多次映射可能带来的时间影响。作为一种具体的实现,本实施例中为加速器预先预取指定大小的连续物理页面到内存缓冲池的步骤是在驱动模块的mt_device_init函数中调用该操作,同时将原来的分配函数和释放函数中涉及物理内存的语句去掉,单纯对位图进行操作,可以解决空闲页面busy的问题。除此之外,由于不用在每次申请的时候都进行一遍物理内存的分配工作,这个版本在时间性能上表现很好。
[0059]
如图3所示,步骤3)中分配连续物理页面的步骤包括:
[0060]
s1、接收到用户对分配连续物理页面接口cmt_malloc的第一调用请求,所述第一调用请求中包含的所需页面数count;
[0061]
s2、通过内存分配器hoard接收第一调用请求,转换并发起对内存分配器hoard中的分配连续物理页面接口mt_malloc的第二调用请求以进入底层分配流程;本实施例在运行时级别,利用内存分配器hoard的内存缓冲池来作为存储指定大小的连续物理页面,通过一次性为应用预留大块内存的方式,减少多次映射可能带来的时间影响;
[0062]
s3、通过dma模块接收第二调用请求,转换并发起对dma模块中的分配连续物理页面接口cont_malloc的第三调用请求以进入连续内存分配流程;
[0063]
s4、通过连续内存分配模块cma接收第三调用请求,转换并执行连续内存分配模块cma中的连续物理页面分配函数_cont_malloc:所述连续物理页面分配函数_cont_malloc首先通过预设的起始页框号查找函数find_base_pfn查找全局位图all_bitmap获取空闲物理页面的起始页框号pfn,然后根据查找得到的起始页框号pfn和所需页面数count向用于
分配物理页面的伙伴系统发出分配物理页面请求以通过伙伴系统执行具体的物理页面分配。
[0064]
在实现了任意cma区域连续分配的功能以后,本实施例方法中对dma层面的连续内存分配算法也进行了改进,以进一步提升算法的时间和空间性能。如图4所示,预设的起始页框号查找函数find_base_pfn查找全局位图all_bitmap获取空闲物理页面的起始页框号pfn的步骤包括:
[0065]
s4.1a、声明临时区域结构cma,从用于记录cma区域zone1~zone
n
的cma_area数组中的任一元素复制通用参数至临时区域结构cma;
[0066]
s4.2a、遍历cma_area数组,累加每个元素对应的位图大小,将每个元素对应的位图大小求和得到全局位图all_bitmap的大小bitmap_maxno;
[0067]
s4.3a、根据分配连续物理页面请求的所需页面数count计算所需位图大小bitmap_count;
[0068]
s4.4a、判断所需位图大小bitmap_count小于全局位图all_bitmap的大小bitmap_maxno是否成立,若成立则跳转执行下一步,否则返回空,结束并退出;
[0069]
s4.5a、将cma_area数组上锁;
[0070]
s4.6a、找到全局位图all_bitmap中一段足够大的连续空间的起始下标bitmap_no;
[0071]
s4.7a、将cma_area数组解锁;
[0072]
s4.8a、判断连续空间的起始下标bitmap_no在全局位图all_bitmap范围内是否成立,若成立则跳转执行下一步,否则返回空,结束并退出;
[0073]
s4.9a、找到连续空间的起始下标bitmap_no对应的连续内存地址分配区域zone
i
,计算对应的空闲物理页面的起始页框号pfn,将空闲物理页面的起始页框号pfn反馈给连续物理页面分配函数_cont_malloc。
[0074]
如图5所示,连续内存分配模块cma中的连续物理页面分配函数_cont_malloc根据查找得到的起始页框号pfn和所需页面数count向用于分配物理页面的伙伴系统发出分配物理页面请求以通过伙伴系统执行具体的物理页面分配的步骤包括:
[0075]
s4.1b、重新将每个zone的bitmap依次映射到全局位图all_bitmap以防止一致性错误;
[0076]
s4.2b、确定空闲物理页面的起始页框号pfn对应的连续内存地址分配区域zone
i

[0077]
s4.3b、判断连续内存地址分配区域zone
i
是否已经足够分配,若连续内存地址分配区域zone
i
足够分配,则调用伙伴系统从连续内存地址分配区域zone
i
中为调用请求执行内存分配并退出;否则,跳转执行下一步;
[0078]
s4.4b、调用伙伴系统首先分配连续内存地址分配区域zone
i
中可分配的尾部空间,然后分配相邻的下一个空闲的连续内存地址分配区域zone
i 1
;判断是否为调用请求分配到足够空间,如果已经分配到足够空间,则结束并退出,否则,将相邻的下一个空闲的连续内存地址分配区域zone
i 1
作为新的连续内存地址分配区域zone
i
,跳转执行步骤s4.3b。
[0079]
参见前文具体步骤,改进后的连续分配算法主要思想是,根据计算出的起始页框号pfn,首先计算能否在一个cma区域内完成分配,若能,则在该起始区域上分配;若不能,则从起始区域开始,分配其从起始页框号pfn往后的剩余尾部空间,以及后续的cma_area。每
次分配都更新一次当前分配的总页数cnt,若cnt大于所需总页数count,则释放最后一块cma_area的尾部多余空间。这样做是因为,起始页框号pfn在一个cma_area上的位置是不固定的,所需总体cma_area数难以精准计算,故选择先占满再释放的方式,保证一定可以分配到足够的空间。改进之后,不再需要判断count与cma区域(page_zones)的关系,不论大小,都可以在全局位图上统一分配。这种改进对cma area的管理较为统一,在cma层面,指定起始页框号pfn和count,省去了在每个小位图上循环比较大小和查找连续空间的步骤,更加快速。同时,在dma层面,该算法也较为健壮,如遇到start_zone无法正常分配的情况,则可以直接跳到相邻的下一个区域,从该区域的头部开始查找,以此类推,直至找到连续的空间。此外,该算法省去了在基础算法中判断当前连续空间是否拥有足够页面的操作。在位图映射过后,原本互不相关的cma相当于能够在全局位图上“看见”彼此的剩余空间大小和位置,这样,就可以直接在全局位图上判断和指定一块足够的连续空间,而不必到具体分配时再频繁地释放、重分配,减少了一些可能被浪费的时间代价。假设总体可分配内存是4个zone,大小均为16mb,现在有三次内存申请,大小分别为8mb、20mb、12mb。基础分配算法中,分配情况如图6所示。图6中子图(a)所示为4个zone的初始情况,在第一个申请i到达时,分配zone 1头部的8mb,如图6中子图(b)所示;第二个申请ii到达时,从zone 4开始,首先把zone 4和zone 3全部占满,然后释放掉zone 3头部的12mb,如图6中子图(c)所示;第三个申请iii到达时,从头向后查找有足够空间的zone,尽管zone 3恰好剩余12mb,但由于zone 2比zone 3更先被扫描,这12mb将在zone 2上分配,如图6中子图(d)所示,最终导致的内存碎片共有24mb,且分别分布在zone 1、zone 2和zone 3。而在本实施例的位图映射算法中,分配情况如图7所示。图7中子图(a)所示为4个zone的初始情况,在第一个申请i到达时,分配zone 1头部的8mb,如图7中子图(b)所示;第二个申请ii到达时,从zone 1开始,首先把zone 1全部占满,然后释放掉zone 2头部的12mb,如图7中子图(c)所示;第三个申请iii到达时,首先把zone 2全部占满,然后释放掉zone 3头部的8mb,如图7中子图(d)所示,最终导致的内存碎片共有24mb,且全部连续分布在zone 3和zone 4。每次申请都依次分配相应大小,在保证对齐的情况下首尾相连,三次申请之后,而由于不需要进行重复查找各cma_area位图的操作,时间上也会减少。
[0080]
如图8所示,步骤3)中则释放连续物理页面的步骤包括:
[0081]
s4.1c、接收到用户对释放连续物理页面接口cmt_free的第四调用请求;
[0082]
s4.2c、通过内存释放器hoard接收第四调用请求,转换并发起对内存释放器hoard中的释放连续物理页面接口mt_free的第五调用请求以进入底层释放流程;
[0083]
s4.3c、通过dma模块接收第五调用请求,转换并发起对dma模块中的释放连续物理页面接口cont_free的第六调用请求以进入连续内存释放流程;
[0084]
s4.4c、通过连续内存释放模块cma接收第六调用请求,转换并执行连续内存释放模块cma中的连续物理页面释放函数_cont_free:所述连续物理页面释放函数_cont_free向用于释放物理页面的伙伴系统发出释放物理页面请求以通过伙伴系统执行具体的物理页面释放。
[0085]
为了区别于原有的系统函数malloc/free,本实施例中将调用新内存机制的函数接口命名为cmt_malloc和cmt_free,在不改变传统编程习惯的情况下,用户可以通过该接口分配或释放连续的物理页面。本实施例中,步骤3)之前还包括修改内存释放器hoard,使
得系统同时兼容分配连续物理页面接口cmt_malloc、原有分配连续物理页面接口malloc,释放连续物理页面接口cmt_free、原有释放连续物理页面接口free的步骤。
[0086]
本实施例中,修改内存释放器hoard的步骤包括:针对修改内存释放器hoard的底层结构实现部分源代码目录heap

layers下函数封装目录wrappers下,首先将所有函数封装文件中的函数暴露出的所有函数名加指定前缀cmt,以免与系统函数库libc中的系统函数冲突;然后将钩子函数封装文件中所有的钩子函数的返回值改为0以避免钩子函数hook调用系统函数库libc中的系统函数,使得内存释放器hoard中的内存、释放相关函数与系统函数库libc中的系统函数相互隔离,通过系统函数库libc中的系统函数响应原有分配连续物理页面接口malloc以及原有释放连续物理页面接口free,通过修改内存释放器hoard响应分配连续物理页面接口cmt_malloc以及释放连续物理页面接口cmt_free。修改内存释放器hoard主要包括下述几个方面:1、hoard系统函数替换。环境变量ld_preload指定程序运行时优先加载的动态连接库,这个动态链接库中的符号优先级是最高的。标准c的各种函数都是存放在libc.so.6的文件中,在程序运行时自动链接。使用ld_preload后,在该路径下的函数将先于libc.so.6中的函数加载。hoard在源文件libhoard.cpp中将替换函数接口封装为cmt_malloc和cmt_free,在这两个接口函数中调用底层实现好的malloc和free函数,然后将其编译为动态库文件libhoard.so,环境变量设置为ld_preload。这样,动态链接库加载过程中提供了初始化函数,可以轻易的获得系统malloc的句柄,再将它做进一步的管理。2、上层函数对接:为了区分系统malloc与cmt_malloc,使两个函数能够同时使用,首先要对hoard的接口函数进行换名。hoard的源代码主要分为三个部分,source是面向用户的接口源码,include是所有需要包含的头文件,heap

layers则是底层结构实现,包括堆实现的源码heaps、锁实现的源码lock、管理线程的源码threads等。换名操作需要在实现hoard包装的heap

layers/wrappers目录下进行修改。首先,本实施例方法中将gnuwrapper.cpp和wrapper.cpp中暴露出的所有函数名加前缀cmt,以改变libhoard中函数的名字,防止和libc的系统函数冲突。其次,将gnuwrapper

hook.cpp中对realloc、memalign等的hook函数返回值改为0,防止libhoard去hook到libc中的相关函数。这样做的目的是将连续物理内存分配的路径和正常系统分配完全错开,在应用调用malloc时,仍然转至原有的系统函数,而调用cmt_malloc时,则会转至hoard。3、底层函数对接:完成对上层用户的对接之后,需要将hoard与实现好的底层也进行对接,以彻底实现通过调用cmt_malloc来调用cont_malloc的目标。hoard中负责向操作系统申请内存的源码位于heap

layers/wrappers目录下的mmapwrapper.cpp中,由mmapwrapper类的map函数实现。hoard针对windows、mac、unix等版本都有不同的实现,本项目基于linux 4.19.46内核,故在unix分支处将设备名改为mttest0,mmap参数修改为prot_read|prot_write和map_shared。由于hoard缓冲池的工作原理是“一次申请大块,多次分配小块”,故而会出现在分配之前重复打开设备的问题,解决办法是将设备符fd设为mmapwrapper类的静态成员变量,初始化时打开设备即可。
[0087]
综上所述,现有分配机制无法提供连续的大片内存空间(物理及虚拟),并且易产生较多的内存碎片,同时linux对合并分散内存所采取的内存迁移机制时间代价较大。本发明将在linux原本的cma机制基础上实现支持大内存连续分配的内存管理机制,最大限度减少可能产生的内存碎片和访存所需的时间开销,并为用户提供简洁的函数接口,不改变其编程习惯。本实施例方法主要包括下述几个部分:基于cma机制将分散的物理地址统一管理
起来。cma机制将内存以page

zone

node的层级结构组织起来,形成可连续访问的内存空间,如图1。在此基础上,本实施例方法中可以实现将连续物理内存与连续虚拟内存的映射的操作。依靠全局位图准确分配内存,减少内存碎片。用全局位图代替每个cma area的本地位图,实现逻辑上的内存连续,以便更清晰地判断何处有足够分配的空闲空间,且消除两次分配间的外部碎片。移植内存分配器以减少额外的时间开销。本实施例方法中选择适用于分布式场景的内存分配器hoard,修改其包装接口以对接本实施例方法中的内存机制,从而大幅度提升访存速度。解决伙伴系统导致的空页面无法通过物理内存的预分配来分配的问题。由于伙伴系统每次分配2的幂数个页面,导致有时在全局位图看来为空的页面,实际上已经被占用,在初始化设备时即将全部内存占用(即预分配),后续申请到达时仅作虚实地址的映射处理,可以有效解决这个问题,并减少时间开销。提供合适的用户接口。为了区别于原有的系统函数malloc/free,本实施例方法中将调用新内存机制的函数接口命名为cmt_malloc和cmt_free,在不改变传统编程习惯的情况下,用户可以通过该接口分配或释放连续的物理页面。
[0088]
此外,本实施例还提供一种基于cma实现支持大内存连续分配的内存管理系统,包括相互连接的微处理器、内存模块以及加速器,该微处理器被编程或配置以执行前述基于cma实现支持大内存连续分配的内存管理方法的步骤。
[0089]
此外,本实施例还提供一种计算机可读存储介质,该计算机可读存储介质中存储有被编程或配置以执行前述基于cma实现支持大内存连续分配的内存管理方法的计算机程序。
[0090]
本领域内的技术人员应明白,本技术的实施例可提供为方法、系统、或计算机程序产品。因此,本技术可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本技术可采用在一个或多个其中包含有计算机可用程序代码的计算机可读存储介质(包括但不限于磁盘存储器、cd

rom、光学存储器等)上实施的计算机程序产品的形式。本技术是参照根据本技术实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
[0091]
以上所述仅是本发明的优选实施方式,本发明的保护范围并不仅局限于上述实施例,凡属于本发明思路下的技术方案均属于本发明的保护范围。应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理前提下的若干改进和润饰,这些改进和润饰也
应视为本发明的保护范围。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献

  • 日榜
  • 周榜
  • 月榜