一种多核间免锁的内存分配方法、装置和电子设备与流程

文档序号:26904770发布日期:2021-10-09 13:48阅读:153来源:国知局
一种多核间免锁的内存分配方法、装置和电子设备与流程

1.本发明属于计算机技术领域,尤其涉及一种多核间免锁的内存分配方法、装置和电子设备。


背景技术:

2.计算机技术的飞速革新给动态内存分配算法带来了新的问题与挑战。在单核cpu时代,内存分配算法需要解决的主要传统问题包括内碎化、外碎化、数据对齐以及局部性访问。然而提升cpu主频的做法目前遇到瓶颈,受制于制造工艺与成本,使得通过传统的方式提升处理器的性能愈发困难,因此cpu逐渐向多核方向发展。高速实时系统应用中,内存管理起着十分关键的作用,由于程序运行阶段的内存分配皆由动态内存分配算法完成,使得动态分配内存在内存管理上特别重要。高速实时系统往往需要频繁的进行内存分配与释放,若每次都想操作系统申请内存,那么一方面每次都需要进行虚拟地址到物理地址的映射,将爱来效率问题,另一方面也不利于系统的稳定性。
3.当前主流的pcie ssd一般都采用多核方案来实现。然而,由于pcie的传输速率远远超过sata的传输带宽,如果需要充分利用前端带宽,就必须减少固件的时延,多核方案的引入,可以将固件的流程分摊到多个cpu核同时执行,减少固件的cpu时间开销,进而提升性能,但是由此带来的技术缺陷是增加了固件的开发难度,例如,在dramless的固件开发中,有限的sram空间需要在多个核间共享使用,如何保证每个cpu都有充足的资源使用?如何保证共享资源的原子访问?这些都是固件开发中需要解决的难题。
4.现有技术对于动态分配算法的问题包括内存碎片问题以及一些内存分配器所使用的策略和机制。例如常用的内存分配器dlmalloc采用最佳适配算法分配内存,并通过相邻内存块合并的方法减少内存碎片,使用双向链表管理小块内存,使得树结构管理大块内存,曾一度被认为是最兼具效率与内存利用率的内存分配算法。当前主流的方案是通过锁来保证每个cpu具有充足的资源使用(已经并且了线性地址向物理地址转换以及请求调页的操作),dlmalloc算法就属于采用单一锁进行保护的算法,然而该算法没有考虑多线程环境下的分配问题。此外,现有技术还采用经典buddy算法进行内存分配,常用于linux内核,也被称为伙伴系统,然而该算法存在外蒜片问题,两个内存块相邻但不是伙伴块的情况下,buddy算法不能将他们连接起来进行分配,并且在应对短生命期内存分配问题时,内存块不断分裂合并会造成较大开销,降低运行效率。即使采用线段树的算法改进碎片问题,延迟合并算法优化频繁拆合内存块引发的效率问题,但在高并发环境下都必须进行互斥访问,效率降低。
5.2004年发明的michael’s分配器具有可扩展性,并且内部的算法为无锁动态内存分配方法,为了实现无锁,该算法将内存分配函数malloc与内存释放函数free拆分为数个原子步骤,是的其他线程无论处于何种状态,本线程都可进行内存分配函数的调用,然而所使用的算法仍然不能获得稳定的动态内存分配,无法实现在dramless的固件开发中,有限的sram空间需要在多个核间共享使用的情况下保证每个cpu都有充足的资源使用,并且确
保对共享资源的原子访问。


技术实现要素:

6.本发明的目的是提供一种高效稳定的、线程间安全无锁的、对内存池进行内存分配的多核间免锁的内存分配方法,不仅保证每个cpu核充分使用内存资源,还可以在分配内存时达到免锁的效果,有利于进一步提升性能。
7.本发明一方面提供了一种多核间免锁的内存分配方法,包括:
8.步骤1,根据cpu核的数量将内存划分为与所述cpu核数量相同且一一对应的多个本地内存池,其中每个本地内存池与不同的cpu核对应,每个所述cpu核在所述多个本地内存池中申请内存资源的情况下不需要加锁;
9.步骤2,第二cpu核所需内存资源小于自身对应的第二本地内存池中的内存资源,则所述第二cpu核从所述第二本地内存池中申请内存资源;否则执行步骤3;
10.步骤3,第二cpu核所需内存资源大于自身对应的第二本地内存池中的内存资源,所述第二cpu核通过多个共享缓冲区从第一cpu核对应的第一本地内存池中申请并使用内存资源。
11.进一步地,所述步骤1对于本地内存池的具体划分根据内存使用的业务范围进行,并且所述本地内存池可以进行实时动态调整。
12.进一步地,所述步骤3包括:
13.步骤31,将所述第一本地内存池中的内存资源写入第一共享缓冲区;
14.步骤32,所述第二cpu核从所述第一共享缓冲区内获取所述第一本地内存池中的内存资源作为第二临时内存资源;
15.步骤33,基于所述第二临时内存资源使用完毕后发送的位于消息队列内的结束信号,所述第二cpu核将所述第二临时内存资源写入第二共享缓冲区;
16.步骤34,所述第一cpu核从所述第二共享缓冲区获取所述第二临时内存资源后,将所述第二临时内存资源重新置于所述第一本地内存池中。
17.进一步地,所述步骤31以及所述步骤33通过写游标wptr实现所述写入;,述步骤32以及所述步骤34通过读游标rptr实现所述获取。
18.进一步地,每个本地内存池中都包含多个页,每个页只有被分配和空闲两种情况,使用位图标记每一个页的状态,位图中每一个比特与一个页对应,若某页被分配则对应比特位为0,若某页空闲则对应比特位为1,然后将所述位图结合原子操作达到所述免锁的内存分配。
19.进一步地,所述多核间免锁的内存分配方法还包括双判机制,即内存申请线程在搜索位图设置为0后再判断一次二级位图中对应切片是否为0,若不为0则重新将搜索位图中相应设置为1。
20.进一步地,当获得所述步骤32中的所述第二临时内存资源后,所述第二临时内存资源与第一本地内存池中的内存资源并不立即进行内存块的合并,而是进行渐进式重合并,其合并过程为一级位图的分布搜索过程,通过位运算在位图中从前向后搜索连续1的个数,随后将这些空闲页合并为大的内存块并设置相应的二级位图与搜索位图;每当合并出一个空闲块,则检查是否超过合并时间限制,若超过,则记录本次进行到一级位图的第几
位,以便下一次合并操作继续执行;若每次合并超时后还没有可以满足需求的内存块,则先向操作系统申请一块内存以满足需求。
21.本发明的第二方面,提供一种多核间免锁的内存分配装置,包括:
22.本地内存池划分模块,根据cpu核的数量将内存划分为与所述cpu核数量相同且一一对应的多个本地内存池,其中每个本地内存池与不同的cpu核对应,每个所述cpu核在所述多个本地内存池中申请内存资源的情况下不需要加锁;
23.核内内存分配模块,第二cpu核所需内存资源小于自身对应的第二本地内存池中的内存资源,则所述第二cpu核从所述第二本地内存池中申请内存资源;否则执行多核间内存分配;以及
24.多核间内存分配模块,第二cpu核所需内存资源大于自身对应的第二本地内存池中的内存资源,所述第二cpu核通过多个共享缓冲区从第一cpu核对应的第一本地内存池中申请并使用内存资源。
25.本发明的第三方面提供一种电子设备,包括处理器和存储器,所述存储器存储有多条指令,所述处理器用于读取所述指令并执行如第一方面所述的方法。
26.本发明的第四方面提供一种计算机可读存储介质,所述计算机可读存储介质存储有多条指令,所述多条指令可被处理器读取并执行如第一方面所述的方法。
27.本发明提供多核间免锁的内存分配方法、装置和电子设备,具有如下有益效果:
28.(1)不仅可以适用于不同的业务模型,而且对内存资源申请进行免锁,使得多核性能达到最大化,并且减少最大时延和波动
29.(2)该实施例运行在高并发环境下,该多核间免锁的内存分配方法的内存分配效率高于普通带锁的内存分配方法,并且随着并发度的提高,这种效率提升变得更为明显。在单线程环境下,当进行连续随机大小内存分配时,分配效率提高约29%;当进行连续固定大小内存分配时,分配效率提高33%。在连续近似大小内存分配时,采用了渐进式重合并算法,由于延迟了内存块的合并,从而提高了内存分配效率。在单生产者多消费者模型的并发环境下,当进行连续随机大小的内存分配时,随着消费者线程的不断增加,传统算法的效率不断下降,并且并发度越高,效率下降越快,这是由于随着线程数量的不断增减,采用锁来实现并发的机制问题暴露,锁的频繁争抢严重降低了算法效率.
30.(3)本方法采用连续的数据结构也有着更高的cache命中率。在一种特殊的运行环境下,即多线程,连续固定内存分配的环境下,本发明在稳定性和分配效率方面更适用于高速实时系统,高并发环境。
附图说明
31.图1为本发明提供的多核间免锁的内存分配方法优选实施例的方法流程图。
32.图2为本发明提供的多核间免锁的内存分配装置的优选实施例的结构示意图。
33.图3为本发明提供的电子设备一种实施例的结构示意图。
具体实施方式
34.下面结合附图和实施例,对本发明的具体实施方式作进一步详细描述。以下实施例用于说明本发明,但不用来限制本发明的范围。
35.本实施例的多核间免锁的内存分配方法,包括:
36.步骤1,根据cpu核的数量将内存划分为与cpu核数量相同且一一对应的多个本地内存池,其中每个本地内存池与不同的cpu核对应,每个cpu核在多个本地内存池中申请内存资源的情况下不需要加锁;
37.步骤2,第二cpu核所需内存资源小于自身对应的第二本地内存池中的内存资源,则第二cpu核从第二本地内存池中申请内存资源;否则执行步骤3;
38.步骤3,第二cpu核所需内存资源大于自身对应的第二本地内存池中的内存资源,第二cpu核通过多个共享缓冲区从第一cpu核对应的第一本地内存池中申请并使用内存资源。
39.其中,根据优选实施方式,步骤1对于本地内存池的具体划分根据内存使用的业务范围进行。
40.步骤3包括:
41.步骤31,将第一本地内存池中的内存资源写入第一共享缓冲区;
42.步骤32,第二cpu核从第一共享缓冲区内获取第一本地内存池中的内存资源作为第二临时内存资源;
43.步骤33,基于第二临时内存资源使用完毕后发送的位于消息队列内的结束信号,第二cpu核将第二临时内存资源写入第二共享缓冲区;
44.步骤34,第一cpu核从第二共享缓冲区获取第二临时内存资源后,将第二临时内存资源重新置于第一本地内存池中。
45.步骤31以及步骤33通过写游标wptr实现写入。步骤32以及步骤34通过读游标rptr实现获取。
46.其中,游标的作用在于将结果集遍历输出,写游标和读游标例如按照如下方式通过环形缓冲区的实现:
47.例如初始状态rptr=wptr=0;其中共享区域buf[size];
[0048]
当其中一个cpu将资源写入共享区域时:
[0049]
if(wptr+1!=rptr)
[0050]
ꢀꢀꢀꢀꢀꢀ
buf[wptr++]=资源;
[0051]
另一个cpu从共享区域中读取资源时:
[0052]
if(rptr<wptr)
[0053]
ꢀꢀꢀꢀ
returnbuf[rptr++]
[0054]
当rptr和wptr达到共享区域的size大小时,重新从0开始
[0055]
wptr=wptr%size;
[0056]
每个本地内存池中都包含多个页,每个页只有被分配和空闲两种情况,使用位图标记每一个页的状态,位图中每一个比特与一个页对应,若某页被分配则对应比特位为0,若某页空闲则对应比特位为1,然后将位图结合原子操作达到免锁的内存分配。其中,免锁的内存分配方法包含一个一级位图,其中每一位对应了当前一个页的使用状态,维护多个空闲表,每个空闲表由搜索位图和二级位图构成,其中二级位图用于标识空闲内存块,为了加快找到第一个空闲块的速度,引入搜索位图,其中每一位对应二级位图中的一个位图切片,每张位图为一个整型数组,其中的一个整型文本称之为位图切片,若位图切片为0,则搜
索位图中对应位为0,否则为1。本实施例中,当存在2
k
大小的空闲内存块时,第k个空闲表的二级位图中对应该空闲内存块首页的比特位被标记为1。
[0057]
在高并发程序中,临界区是影响性能的主要原因,当使用锁作为同步方式时,同一时刻只有一个线程可以处于临界区,而免锁算法允许多个线程互不阻塞的运行,因此采用原子操作时,在临界区可以有多个线程同时进入,普通指令可以并发执行。并且采用了连续的数据结构,降低了cache miss概率,并且原子操作的性能约为锁的2倍,因此原子操作的消耗总体小于采用锁作为同步方式的消耗。此外,该免锁内存分配方法可以在内存总量不过大时,通过搜索位图快速定位二级位图切片,而以较低的时间复杂度申请和释放内存块,当内存总量较大时通过将总内存分为多个较小的本地内存块,之后在每个较小的内存块上调用该内存分配方法。
[0058]
一个原子操作具有原子性,但多个原子操作却不一定是原子的,因此虽然设置搜索位图和设置二级位图的操作都是原子的,但二者结合起来却不一定是并发安全的。该问题可以通过加锁解决,但是存在加锁解决方案的通病,因此本实施例的多核间免锁的内存分配方法还包括双判机制,即内存申请线程在搜索位图设置为0后再判断一次二级位图中对应切片是否为0,若不为0则重新将搜索位图中相应设置为1。
[0059]
作为优选的实施方式,当获得步骤32中的第二临时内存资源后,第二临时内存资源与第一本地内存池中的内存资源并不立即进行内存块的合并,而是进行渐进式重合并,其合并过程为一级位图的分布搜索过程,内存分配者会通过位运算在位图中从前向后搜索连续1的个数,随后将这些空闲页合并为尽量大的内存块并设置相应的二级位图与搜索位图;每当合并出一个空闲块,则检查是否超过合并时间限制,若超过,则记录本次进行到一级位图的第几位,以便下一次合并操作继续执行;若每次合并超时后还没有可以满足需求的内存块,则先向操作系统申请一块内存以满足需求。通过渐进式合并,该方法比传统的内存分配方法减少了频繁申请释放内存时不断拆合带来的负载,减少了外碎片,可以合并任意相邻的页。
[0060]
本实施例中相关的算法包括:
[0061]
一、内存块分配算法
[0062]
分配的核心是一个位图的搜索核设置函数,通过该函数得到要分配的物理块,分配算法首先计算满足申请内存所需最小页数,并找到第一个合适的区间idx,接着使用汇编指令bsfl找到idx个区间的搜索位图的第一个1bit,将其索引保存在变量firstbit中,并搜索二级位图的第firstbit个位图切片,根据搜索结果找到要分配内存块的首地址,最后将多余的内存划分到其他区间并设置相应的位图,其流程描述如下:
[0063]
输入:请求内存的大小(memsize单位:字节)
[0064]
输出:分配内存块的首地址
[0065]
第一步,根据请求内存大小memsize,计算出最少需要n个页才能满足需求;
[0066]
第二步,从最小满足需求的内存块区间开始查找,找到第一个搜索位图不为0的区间;
[0067]
第三步,找到该搜索位图中第一个1比特,记录其索引idx;
[0068]
第四步,搜索二级位图中第idx个位图切片,找到第一个1比特,将比特位索引记录在firstbit;
[0069]
第五步,在本地内存池中道道idx*32+firstbit个页;
[0070]
第六步,将以该页起始的内存块分为两部分,第一部分为满足需求的最小内存块,第二部分为剩余内存块;
[0071]
第七步,将剩余内存块归入相应区间,即设置二级位图与搜索位图;
[0072]
第八步,根据分配内存块的起始位置大小设置一级位图,并返回该内存块首地址。
[0073]
二、内存块释放算法设计
[0074]
内存块释放算法的主体是地址的计算以及位图的搜索与设置。该算法根据内存块起始地址,内存池起始地址以及页大小,计算出该内存块在内存池中的起始地址,并根据这些信息设置一级、二级以及搜索位图,具体步骤包括:
[0075]
输入:释放内存块的起始地址(void*pdata)
[0076]
输出:无
[0077]
第一步,计算内存块起始地址pdata相对于内存池起始地址的偏移量offset;
[0078]
第二步,根据偏移量offset与页大小pagesize计算出内存块起始页索引pageidx=offset/pagesize;
[0079]
第三步,设置内存块起始页的页描述符,页描述符包括以该页为起始的内存块的使用情况,内存块大小等;
[0080]
第四步,根据释放内存块大小,找到相应区间,再由起始页搜索pageidx找到二级位图中对应的位图切片,设置相应比特位;
[0081]
第五步,若对应位图切片之前的值为0,那么还需要设置该切片在搜索位图中对应的比特位;
[0082]
第六步,设置一级位图。
[0083]
三、渐进式重合并算法设计
[0084]
渐进式重合并算法首先计算当前重合并进行到了第几页,并将进度保存到remergeidx中,找到一级位图第remergeidx位起第一个1bit和第一个0bit,计算二者差值即连续空闲页的大小,根据空闲大小将其划分到相应的区间并设置相应区间的位图,若此次合并后,重合并算法总用时超过了最大限制时间,则跳出重合并算法,具体步骤包括:
[0085]
输入:无
[0086]
输出:无
[0087]
第一步,获取系统时间starttime,作为本次重合并起始时刻;
[0088]
第二步,计算当前重合并进度,即上次重合并操作进行到了一级位图的哪一个比特,将比特的索引值记录在remergeidx中;
[0089]
第三步,在一级位图中,自第remergeidx个比特起向后连续寻找1比特;
[0090]
第四步,根据连续1比特的个数,得到内存块的大小,将该内存块划分至一个或多个区间,且有限划分至大内存块区间;
[0091]
第五步,获取系统时间endtime;
[0092]
第六步,计算该次重合并持续时间,endtime

starttime,若超过最大时间限制time_limit,则立刻结束重合并;
[0093]
第七步,若未超时则回到第二步。
[0094]
实施例一
[0095]
参图1所示,本实施例一提供了一种多核间免锁的内存分配方法(算法),基于本地资源池和共享缓冲区来实现。实施例一以双cpu核(以下采用core表示)为例来说明算法的实现细节,其中展示了core 2申请内存资源的过程,core 1的流程与之类似或完全相同,只是对调或者更换内存资源。在系统启动阶段,根据两个core的业务情况将内存划分为两个本地内存池,这两个本地内存池分属于不同的cpu核;每个cpu核在本地内存池中申请内存资源时是不需要加锁的。在内存划分过程中,要保证core的划分能保证基本业务的运行即可,例如core1上的80%的场景需要8个资源,极端情况需要16,则只需要划分8个即可。
[0096]
具体过程包括:
[0097]
step1:大部分场景下(即本身对应的内存资源足够使用的情况下),core 2都从本地内存池2中申请内存资源;
[0098]
step2:当需要从本地内存池1中申请时,将本地内存池1中的资源通过写游标wptr写入共享缓冲区ring buffer 0;
[0099]
step3:core 2从共享缓冲区ring buffer 0通过读游标rptr读取内存资源作为临时内存资源;
[0100]
step4:临时内存资源被使用完毕后,core 2将属于本地资源池1的内存资源通过写游标wptr写入共享缓冲区ring buffer 1;
[0101]
step5:core 1从ring buffer 1通过读游标rptr读取该临时内存资源后,将该临时内存资源归还至本地内存池1。
[0102]
上述整个过程不需要添加锁互斥;如果出现本地资源池划分不合理的情况时,可以将两个本地资源池进行动态调整。
[0103]
实施例二
[0104]
参考图2,本发明提供一种多核间免锁的内存分配装置,包括
[0105]
本地内存池划分模块201,根据cpu核的数量将内存划分为与cpu核数量相同且一一对应的多个本地内存池,其中每个本地内存池与不同的cpu核对应,每个cpu核在多个本地内存池中申请内存资源的情况下不需要加锁;
[0106]
核内内存分配模块202,第二cpu核所需内存资源小于自身对应的第二本地内存池中的内存资源,则第二cpu核从第二本地内存池中申请内存资源;否则执行多核间内存分配;
[0107]
多核间内存分配模块203,第二cpu核所需内存资源大于自身对应的第二本地内存池中的内存资源,第二cpu核通过多个共享缓冲区从第一cpu核对应的第一本地内存池中申请并使用内存资源。
[0108]
该装置可通过上述实施例一提供的多核间免锁的内存分配方法实现,具体的实现方法可参见实施例一中的描述,在此不再赘述。
[0109]
本发明还提供了一种存储器,存储有多条指令,所述指令用于实现如实施例一所述的方法。
[0110]
如图3所示,本发明还提供了一种电子设备,包括处理器301和与所述处理器301连接的存储器302,所述存储器302存储有多条指令,所述指令可被所述处理器加载并执行,以使所述处理器能够执行如实施例一所述的方法。
[0111]
通过该多核间免锁的内存分配方法(算法)和装置,大部分场景,cpu核在本地存储
池中申请资源,保证了性能最优;当需要跨核申请时,也可以通过免锁的共享缓冲区方式实现。
[0112]
尽管已描述了本发明的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本发明范围的所有变更和修改。显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包含这些改动和变型在内。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1