xenomai用户态实时内存分配器测试对比
目录
- xenomai用户态实时内存分配器测试对比
- 一、xenomai用户态、内核态内存分配器介绍
- 二、测试流程
- 三、测试结果
- 四、详细输出数据
- coreheap(kernel)
- heapmem
- tlsf
- pshared
实时动态内存分配器是实时系统中保障任务高效运行的核心组件之一。在实时应用场景中,内存分配的确定性、时效性与可靠性直接影响系统的实时性能 —— 尤其是在工业自动化、机器人控制、航空航天等对响应时间有严苛要求的领域,传统通用内存分配器(如 glibc 的 malloc)因存在不可预测的延迟和碎片问题,往往难以满足实时性需求。
Xenomai 作为一款成熟的实时操作系统框架,针对实时环境的特殊需求,提供了一系列经过工业级场景长期验证的动态内存分配器。这些分配器在设计上以 “确定性延迟” 为核心目标,确保内存操作的响应时间可控,同时兼顾低碎片率和高吞吐量。
它们均经过工业自动化领域的严苛考验,具备稳定、高效、可预测的特点。对于开发者而言,这些分配器不仅可供xenomai实时应用直接调用,也可移植直接集成到实时应用中以快速满足需求。
本文先简单介绍 Xenomai 中几种实时动态内存分配器,随后给出在不同条件下的他们的分配释放时间、开销及碎片化率。
一、xenomai用户态、内核态内存分配器介绍
老生常谈,引用之前文章的一段话:
通常,操作系统的内存管理,内存分配算法一定要快,否则会影响应用程序的运行效率,其次是内存利用率要高。
但对于硬实时操作系统,首先要保证实时性,即确定性,不同内存大小的分配释放时间必须是时间确定的。
无论linux还是xenomai,内核在服务或管理应用程序过程中经常需要内存分配,通常linux内存的分配与释放都是时间不确定的,例如,惰性分配导致的缺页异常、页面换出和OOM会导致大且不可预测的延迟,不适用于受严格时间限制的实时应用程序。
xenomai作为硬实时内核,不能使用linux glibc这样的内存分配释放接口,为此xenomai采取的措施是
- 在内核态,在xenomai内核初始化时,先调用__vmalloc()从linux管理的ZONE_NORMAL中分配 一片内存,然后由xenomai自己来管理这片内存,且xenomai提供的内存分配释放时间确定的,这样就不会因为内存的分配释放影响实时性(该内存管理代码量非常少,有效代码数3百行左右,实现精巧,值得研究利用)。本文中也将该内存分配器加入了对比,用coreheap表示。
关于内核态xnheap分配器本博客有专门写过文章解析,详见https://www.cnblogs.com/wsg1100/p/13258388.html
- 在用户态,glibc的内存管理不具有时间确定性,RT应用只能在程序初始化时分配并访问(避免运行中产生pagefault),运行中不能使用,否则会严重影响实时性。为此xenomai实时应用库libcobalt为RT应用实现了多个时间确定的内存动态分配释放heap,供实时任务运行中分配内存。它们分别是xnheap、tlsf、heapmem。
综上,xenomai系统中用户态及内核态共有4种实时动态内存分配器:
- coreheap
xenomai内核实时动态内存分配器,为内核态实时任务管理RTDM等提供实时动态内存分配。
- xnheap
xnheap源自 Xenomai 原始的双内核中的 xnheap 。它足够简单且高效,用于管理通过 tmpfs 文件支持的动态内存分配,并且可以在用户空间的多个进程之间共享,实现源码为heapobj-pshared.c,通过xenoomai库编译配置选项--enable-pshared=enable启用多个进程之间共享对象时使用。
注:内核中的xnheap在xenomai 3.1版本有所优化,使用红黑树代替了链表,所以xenomai 3.1版本及以上的用户态xnheap与内核态xnheap性能有所区别。
- tlsf(Two-Level Segregate Fit)
TLSF 是一种通用动态内存分配器,专门设计用于满足实时要求:
- 有限响应时间 。确定的内存分配和释放的最坏情况执行时间 (WCET) 必须提前知道,并且与应用程序数据无关。TLSF 具有恒定成本 O(1)。
- 快。 除了有限成本之外,分配器还必须足够高效和快速。
- 高效内存利用 .传统上,实时系统运行时间较长,有些(嵌入式应用程序)对内存大小有很强的限制。碎片化会对此类系统产生重大影响。它会急剧增加,并降低系统性能。衡量此效率的一种方法是分配器产生的内存碎片。TLSF 已在数百种不同的负载(实时任务、通用应用程序等)中进行了测试,平均碎片率低于 15%。 测得的最大碎裂率低于 25%。
- TLSF 已包含在多个 Linux 发行版和应用程序中。尽管 TLSF 在许多场景中运行良好,但它在硬/软实时应用程序的应用程序中脱颖而出,由于数据大小的高度可变性或对新情况的适应性,该应用程序使用显式内存分配,具有很高的灵活性要求。TLSF在以下领域表现突出:
- 硬/软实时系统:需严格满足时间约束的场景(如工业控制、自动驾驶)。
- 动态内存需求高的场景:适应数据规模多变或需动态调整内存的灵活架构(如多媒体处理、3D重建)。
- 资源受限环境:嵌入式设备、网络设备(路由器/交换机)、游戏引擎等内存敏感场景。
- 高可靠性应用:对内存碎片敏感的长周期运行系统(如通信基站、医疗设备)。
源码位于tlsf\tlsf.c,tlsf版本为2.4.6版本。
- heapmem
heapmem为《Marshall K. McKusick与Michael J. Karels在"4.3BSD Unix内核通用内存分配器设计》(USENIX 1988会议)中描述的分配器变体实现,详见http://docs.FreeBSD.org/44doc/papers/kernmalloc.pdf。其核心机制为:空闲页面列表通过 AVL 树进行维护,以实现对多页面内存范围的快速查找;而存储分桶内存的页面则使用快速分配位图来管理其内部块。
heapmem和tlsf在xenomai库中用于alchemy、VxWorks、psos等skin接口中task、sem等对象管理的分配释放,编译xenomai库时通过configure配置参数选择--with-localmem=,若没有指定,默认使用xnheap。
二、测试流程
按装xenomai后,运行如下命令即可得出结果:- ./smokey --run=8-10,31 --verbose=2
复制代码
- 初始化:设置线程为高优先级实时任务,避免调度干扰测试精度,以固定块大小和随机大小两种方式进行下面2、3测试。
- 内存分配测试
- 核心逻辑:持续分配固定大小的内存块,记录每次分配的耗时,直到无法分配为止。
- 模式检查(MEMCHECK_PATTERN):向内存块写入特定模式数据,用于后续验证内存是否被意外修改
- 随机释放(MEMCHECK_SHUFFLE):若开启随机释放(+shuffle),则打乱释放顺序,模拟真实场景中内存块无序释放的情况,更贴近实际使用,记录每次释放的耗时。
- 碎片率计算:当释放一半内存时,记录最大连续空闲块大小,评估堆管理器的抗碎片能力。
测试堆管理器在多次分配 - 释放循环后的稳定性,验证是否存在累计错误(如内存泄露、性能退化)。
- 统计分配释放最大、平均耗时,分配开销,碎片化等数据。
三、测试结果
以下数据基于rockchip rk3562, linux 5.10.109 + xenomai 3.2.4测试,仅供参考。
HeapTest TypePerformance MetricsWorst Alloc (µs)Worst Free (µs)Avg Max Alloc (µs)Avg Max Free (µs)Avg Alloc (µs)Avg Free (µs)Avg Overhead (%)Avg Fragmentation (%)coreheapFixed Blocks3.22.61.01.10.60.60.036.1Notable Cases: Max alloc: 3.2µs (256k@64), Max free: 2.6µs (512k@16)heapmemFixed Blocks8.86.10.91.30.40.50.040.1Notable Cases: Max alloc/free: 8.8µs/6.1µs (8k@16)tlsfFixed Blocks19.84.11.00.80.40.414.938.5Notable Cases: Max alloc: 19.8µs (8k@16)psharedFixed Blocks3.538.51.01.80.40.60.039.4Notable Cases: Max free: 38.5µs (1024k@16)coreheapRandom Blocks2.62.60.70.90.80.713.811.1heapmemRandom Blocks3.83.20.71.10.60.813.911.9tlsfRandom Blocks2.62.60.80.60.70.512.713.7psharedRandom Blocks2.33.50.81.20.70.913.911.9无论是固定块大小分配还是随机大小分配,这几个实时内存分配器都很优秀。
四、详细输出数据
测试输出说明:
- HEAPSZ 测试堆大小
- BLOCKSZ 测试块大小
- NRBLKS 堆中可分配的块数量
- AVG-A 分配块的平均时间(微秒)
- AVG-F 释放块的平均时间(微秒)
- MAX-A 分配块的最大时间(微秒)
- MAX-F 释放块的最大时间(微秒)
- OVRH% 开销,堆实际占用大小(arena_size)与可用大小(heap_size)的差值,反映管理开销。
- FRAG% 外部碎片 ,(1.0 - largest_free / maximum_free) * 100.0
- FLAGS +shuffle: 随机释放 +hot: 在初始分配/释放后测量(热堆)
coreheap(kernel)
- === running memory_heapmem ===
- seq_heap_size=2048k
- random_alloc_rounds=1024
- pattern_heap_size=128k
- pattern_check_rounds=128
- [SEQUENTIAL ALLOC->FREE, ^2 BLOCK SIZES] ON 'coreheap'
- sorted by: max alloc time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 256k 64 4096 0.5 0.5 3.2 2.0 0.0 99.2 +shuffle +hot
- 1024k 16 65536 0.5 0.5 2.3 2.0 0.0 100.0 +shuffle +hot
- 1024k 2k 512 0.6 1.1 2.3 1.8 0.0 94.1 +shuffle
- 1024k 256 4096 0.6 0.9 2.3 2.3 0.0 98.9 +shuffle
- ... (364 results following) ...
- sorted by: max free time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 512k 16 32768 0.5 0.5 2.3 2.6 0.0 100.0 +shuffle
- 1024k 256 4096 0.6 0.9 2.3 2.3 0.0 98.9 +shuffle
- 1024k 32 32768 0.5 0.6 2.3 2.3 0.0 99.9 +shuffle
- 512k 16 32768 0.5 0.5 2.3 2.3 0.0 100.0 +shuffle +hot
- ... (364 results following) ...
- sorted by: max overhead
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 512k 16 32768 0.5 0.5 2.3 2.6 0.0 100.0 +shuffle
- 1024k 256 4096 0.6 0.9 2.3 2.3 0.0 98.9 +shuffle
- 1024k 32 32768 0.5 0.6 2.3 2.3 0.0 99.9 +shuffle
- 512k 16 32768 0.5 0.5 2.3 2.3 0.0 100.0 +shuffle +hot
- ... (364 results following) ...
- sorted by: max fragmentation
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 16 65536 0.5 0.5 2.0 2.3 0.0 100.0 +shuffle
- 1024k 16 65536 0.5 0.5 2.3 2.0 0.0 100.0 +shuffle +hot
- 1024k 32 32768 0.5 0.6 2.3 2.3 0.0 99.9 +shuffle
- 1024k 32 32768 0.5 0.5 2.3 2.3 0.0 99.9 +shuffle +hot
- ... (364 results following) ...
- overall:
- worst alloc time: 3.2 (us)
- worst free time: 2.6 (us)
- average of max. alloc times: 1.0 (us)
- average of max. free times: 1.1 (us)
- average alloc time: 0.6 (us)
- average free time: 0.6 (us)
- average overhead: 0.0%
- average fragmentation: 36.1%
- [SEQUENTIAL ALLOC->FREE, RANDOM BLOCK SIZES] ON 'coreheap'
- sorted by: max alloc time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 64k 113 512 0.5 0.6 2.6 1.8 11.7 96.5 +shuffle
- 32k 159 128 0.6 0.6 2.6 1.2 37.9 0.0
- 512k 127k 4 1.2 1.3 2.3 2.0 0.2 0.0 +shuffle
- 512k 228k 2 1.8 0.9 2.3 0.9 10.7 0.0 +shuffle
- ... (32764 results following) ...
- sorted by: max free time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 7 65536 0.5 0.5 1.5 2.6 56.2 100.0 +shuffle
- 512k 82k 6 0.6 1.2 0.6 2.6 2.9 33.3 +shuffle
- 512k 45 8192 0.5 0.5 2.0 2.3 29.7 0.0
- 1024k 479k 2 1.0 2.2 0.9 2.3 6.4 0.0 +shuffle
- ... (32764 results following) ...
- sorted by: max overhead
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 7 65536 0.5 0.5 1.5 2.6 56.2 100.0 +shuffle
- 1024k 268 2048 0.5 0.6 2.0 0.9 47.7 95.4 +shuffle +hot
- 1024k 280 2048 0.6 0.6 2.0 0.9 45.3 0.0
- 1024k 666 1024 0.6 1.1 1.2 1.8 35.0 93.8 +shuffle
- ... (32764 results following) ...
- sorted by: max fragmentation
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 2k 409 0.5 0.9 1.2 1.5 0.5 96.1 +shuffle
- 1024k 2k 409 0.5 0.6 0.9 1.2 2.3 96.6 +shuffle +hot
- 1024k 5k 186 0.5 0.6 0.6 2.0 1.7 94.6 +shuffle +hot
- 1024k 4k 227 0.5 0.6 1.2 2.0 2.5 94.7 +shuffle +hot
- ... (32764 results following) ...
- overall:
- worst alloc time: 2.6 (us)
- worst free time: 2.6 (us)
- average of max. alloc times: 0.7 (us)
- average of max. free times: 0.9 (us)
- average alloc time: 0.8 (us)
- average free time: 0.7 (us)
- average overhead: 13.8%
- average fragmentation: 11.1%
复制代码 heapmem
tlsf
pshared
pshared用于进程间共享对象内存分配,由配置项--enable-pshared配置,和--with-localmem决定:
- 如果配置了--enable-pshared=enable,则使用xnheap(即pshared)。
- 如果配置了--enable-pshared=disable,则根据--with-localmem的配置选择:
a. 如果--with-localmem=tlsf,则使用tlsf。
b. 如果--with-localmem=heapmem,则使用heapmem。
c. 如果未配置--with-localmem,则使用glibc malloc/free接口。
这里测试环境--enable-pshared=enable,所以其实际测试的是xnheap- === running memory_pshared ===
- seq_heap_size=2048k
- random_alloc_rounds=1024
- pattern_heap_size=128k
- pattern_check_rounds=128
- [SEQUENTIAL ALLOC->FREE, ^2 BLOCK SIZES] ON 'pshared'
- sorted by: max alloc time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 16 65536 0.3 0.4 3.5 38.5 0.0 0.0
- 8k 16 512 0.3 0.4 3.2 19.0 0.0 0.0
- 1024k 2k 512 0.4 0.6 2.0 1.2 0.0 96.9 +shuffle +hot
- 1024k 1k 1024 0.4 0.6 2.0 1.5 0.0 98.2 +shuffle +hot
- ... (364 results following) ...
- sorted by: max free time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 16 65536 0.3 0.4 3.5 38.5 0.0 0.0
- 512k 16 32768 0.3 0.4 1.2 36.5 0.0 0.0
- 256k 16 16384 0.3 0.4 1.5 26.5 0.0 0.0
- 128k 16 8192 0.3 0.4 0.9 19.8 0.0 0.0
- ... (364 results following) ...
- sorted by: max overhead
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 16 65536 0.3 0.4 3.5 38.5 0.0 0.0
- 512k 16 32768 0.3 0.4 1.2 36.5 0.0 0.0
- 256k 16 16384 0.3 0.4 1.5 26.5 0.0 0.0
- 128k 16 8192 0.3 0.4 0.9 19.8 0.0 0.0
- ... (364 results following) ...
- sorted by: max fragmentation
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 16 65536 0.3 0.4 2.0 4.1 0.0 100.0 +shuffle
- 1024k 16 65536 0.3 0.3 1.8 2.0 0.0 100.0 +shuffle +hot
- 1024k 32 32768 0.3 0.4 1.8 3.2 0.0 100.0 +shuffle
- 1024k 32 32768 0.3 0.3 2.0 1.8 0.0 100.0 +shuffle +hot
- ... (364 results following) ...
- overall:
- worst alloc time: 3.5 (us)
- worst free time: 38.5 (us)
- average of max. alloc times: 1.0 (us)
- average of max. free times: 1.8 (us)
- average alloc time: 0.4 (us)
- average free time: 0.6 (us)
- average overhead: 0.0%
- average fragmentation: 39.4%
- [SEQUENTIAL ALLOC->FREE, RANDOM BLOCK SIZES] ON 'pshared'
- sorted by: max alloc time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 139k 7 1.0 1.1 2.3 1.5 4.7 50.0 +shuffle
- 1024k 13k 75 0.5 0.8 2.3 1.5 3.5 0.0
- 1024k 76k 13 0.6 0.8 2.3 1.5 2.5 0.0
- 1024k 427k 2 1.8 1.5 2.3 1.8 16.5 0.0 +shuffle
- ... (32764 results following) ...
- sorted by: max free time
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 512k 15 32768 0.3 0.3 0.9 3.5 6.2 100.0 +shuffle
- 64k 21k 2 1.2 2.3 0.9 3.2 33.3 0.0
- 1024k 333k 3 1.1 1.8 1.5 3.2 2.3 0.0
- 32k 5k 5 0.8 1.6 1.2 3.2 15.4 0.0
- ... (32764 results following) ...
- sorted by: max overhead
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 82 8192 0.4 0.4 2.0 1.2 35.9 0.0 +hot
- 1024k 338 2048 0.4 0.7 2.0 1.5 34.0 0.0
- 1024k 341k 2 0.9 0.9 0.9 1.2 33.4 0.0 +hot
- 1024k 341k 2 1.0 1.0 0.9 1.2 33.4 0.0 +shuffle +hot
- ... (32764 results following) ...
- sorted by: max fragmentation
- HEAPSZ BLOCKSZ NRBLKS AVG-A AVG-F MAX-A MAX-F OVRH% FRAG% FLAGS
- 1024k 1k 682 0.4 1.3 1.8 2.0 3.7 97.7 +shuffle
- 1024k 1k 682 0.4 0.7 0.9 1.5 4.5 97.7 +shuffle +hot
- 1024k 2k 409 0.4 0.7 0.9 1.5 3.5 96.1 +shuffle +hot
- 1024k 7k 128 0.4 0.7 1.5 1.2 0.4 92.2 +shuffle +hot
- ... (32764 results following) ...
- overall:
- worst alloc time: 2.3 (us)
- worst free time: 3.5 (us)
- average of max. alloc times: 0.8 (us)
- average of max. free times: 1.2 (us)
- average alloc time: 0.7 (us)
- average free time: 0.9 (us)
- average overhead: 13.9%
- average fragmentation: 11.9%
复制代码 出处:http://www.cnblogs.com/wsg1100/本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |