Page 517 - 《软件学报》2024年第4期
P. 517
欧阳湘臻 等: 榫卯: 一种可组合的定制化内存分配框架 2095
缓存, 其最大 RSS 的几何平均值为 tcmalloc 的 86.8%. 两者对比减少了 7.7% 的内存占用, 说明核心感知的线程缓
存能够改善内存分配器的内存利用率.
● 关于问题 4 的分析. wfslab 是高性能, 低延迟的无锁/无等待分配器, 它通过组合低延迟的层级函数以及每个
层级的定制, 尽可能降低最差情况内存请求延迟. 由图 9, 图 10 可知, wfslab 取得了所有内存分配器中最低的最差
情况内存请求延迟. 其 99.999 9% 内存 malloc/free 请求的延迟分布百分位对应的延迟仅为 61.1 μs/10.3 μs (x86/64
平台) 和 58.3 μs/80.3 μs (aarch64 平台). 同时, 由表 4 可以得到, wfslab 的基准测试执行时间的几何平均值小于所
有基于锁的分配器, 但与目前最先进的无锁分配器 mimalloc 和 snmalloc 还存在差距. 具体地, 从图 5 和图 6 可以
看出, 在存在线程远程释放情形的 larson, sh6bench, sh8bench 以及 glibc-thread 基准测试项上, wfslab 的执行时间
要比 snmalloc 和 mimalloc 略高. 这是因为 wfslab 为降低最差情况内存请求延迟, 舍弃了远程释放缓存批量释放的
设计. 虽然批量释放有助于提升平均性能, 但释放过程中线程可能会频繁访问大量空闲内存块, 造成较多的 cache
未命中和 TLB 未命中, 从而导致最差情况内存请求延迟增加. 不过, 同样因为 wfslab 未采用远程释放缓存的设计,
其内存利用率也有所改善, 其最大 RSS 的几何平均值相较于 mimalloc/snmalloc 低 2.8%/12.1% (x86/64 平台) 和
16.2%/24.4% (aarch64 平台). 此外, 由图 5 和图 6 可以看出 wfslab 在单线程的基准测试项的表现稍差, 例如 cfrac,
espresso, glibc-simple. 这主要是因为 wfslab 即使在单线程场景下也使用相对耗时的原子操作. wfslab 的实验结果
表明立足于榫卯框架的组合性和定制性, 通过系统的设计取舍, 能够有效降低分配器的最差情况内存请求延时.
● 关于问题 5 的分析. 参与实验对比的内存安全分配器各自采用了不同的内存漏洞缓解措施, 这些内存漏洞
缓解措施可能对分配器执行时间和内存占用造成较大的影响, 因此本文无法直接对分配器进行对比. 不过, 通过比
较增加附加层的 wfslabs, hslabd 与 tlsfccsd 与原始的 wfslab, hslab 和 tlsfcc 可以得到这些附加层的开销. 根据表 4
中的执行时间和最大 RSS 几何平均值, 比较 wfslab 和 wfslabs 可以发现, 内存块尾部增加异或校验字的 tail_chksum
附加层的执行时间/内存占用开销为 13.5%/10.6% (x86/64 平台) 和 34.0%/10.2% (aarch64 平台); 比较 hslab 和
hslabd 可以发现, 采用 64 KB 释放隔离区和内存块头部魔数校验的 delayed 附加层的执行时间/内存占用开销为
11.6%/12.3% (x86/64 平台) 和 10.9%/10.3% (aarch64 平台); 比较 tlsfcc 和 tlsfccsd 可以发现, 采用以上两种附加层
的执行时间/内存占用开销为 10.4%/11.1% (x86/64 平台) 和 32.1%/28.7% (aarch64 平台). 实验结果显示, 叠加两个
附加层的开销并非线性的. 同时, 附加层的开销在 x86/64 和 aarch64 两个实验平台也显示出了显著的差别. 这可能
是受 CPU 指令流水线, 硬件 cache 大小与分配算法的影响. 为了比较附加层的组合开销, 本文选取 mimalloc 与
smimalloc 作为对比, smimalloc 在空闲链表中使用异或校验, 其执行时间/内存占用开销为 27.8%/23.6% (x86/64 平
台) 和 42.2%/14.8% (aarch64 平台), 远高于 wfslabs 和 hslabd 的开销. 至此实验结果显示, 榫卯框架能在不改变原
始算法的情况下, 通过组合附加层级, 以较低的开销为内存分配器增加可定制的内存漏洞缓解措施和错误处理策略.
5 总 结
本文从函数式编程视角审视内存分配流程, 基于函数可组合性提出了一种可组合的定制化内存分配框架榫
卯. 榫卯框架将系统内存分配抽象为多个互不耦合的内存分配函数的组合, 这些内存分配函数可以扩展出策略槽
提供更高的组合性和定制性. 该内存分配框架基于标准 C 实现, 依赖 C 预处理器提供的元编程特性实现层级函数
组合的零性能开销. 开发者能够通过组合与定制分配器的层级函数, 快速构建出适合应用场景的内存分配器. 本文
使用榫卯框架构建了 3 种为不同应用场景优化的内存分配器实例, 通过运行基准测试与现有内存分配器进行对
比. 实验结果证明了榫卯框架的有效性.
References:
[1] Donahue SM, Hampton MP, Deters M, Nye JM, Cytron R, Kavi KM. Storage allocation for real-time, embedded systems. In: Proc. of the
1st Int’l Workshop on Embedded Software. Tahoe City: Springer, 2001. 131–147. [doi: 10.1007/3-540-45449-7_10]
[2] Puaut I. Real-time performance of dynamic memory allocation algorithms. In: Proc. of the 14th Euromicro Conf. on Real-time Systems.
Euromicro RTS 2002. New York: IEEE, 2002. 41–49. [doi: 10.1109/EMRTS.2002.1019184]
[3] Kanev S, Darago JP, Hazelwood K, Ranganathan P, Moseley T, Wei GY, Brooks D. Profiling a warehouse-scale computer. In: Proc. of