Page 511 - 《软件学报》2024年第4期
P. 511
欧阳湘臻 等: 榫卯: 一种可组合的定制化内存分配框架 2089
参与对比的其他内存分配器及其代码版本在表 4 中会呈现, 其中分配器简称的对应关系如下: sys (glibcmalloc),
tc (tcmalloc), je (jemalloc), hd (Hoard), tbb (tbbmalloc), sn (snmalloc), mi (mimalloc), smi (smimalloc), dh (Diehard). 这
些内存分配器均采用 mimalloc-bench (https://github.com/daanx/mimalloc-bench) 开源库的编译脚本进行编译. 相关
研究中提到的 Mesh 和 supermalloc 分配器无法在 aarch64 平台编译运行, 因此无法参与实验对比. 对于通过榫卯
框架构造的内存分配器 tlsfcc, hslab 和 wfslab, 本文使用 gcc -fPIC 命令编译为动态链接库, 启用-O3 优化参数. 其
中 x86/64 平台编译使用-mno-see 参数禁止使用 SSE 寄存器, 避免操作系统上下文切换时保存 SSE 寄存器的额外
开销对实验结果造成影响. 同时, 由于 wfslab 中使用的 treiber 无锁栈的 x86 实现依赖 CAS2 原子操作, 必须增加
-mcx16 参数允许使用 CMPXCHG16b 指令. aarch64 平台编译需要增加-march=armv8-a+lse 参数, 允许编译器使用
armv8.1a 新增的 CAS 和 LDADD 原子操作指令, 确保部分层级函数中使用的原子操作原语被正确地编译. 此外,
编译 TLSF 依赖计算前导零函数, x86 上有两种指令都能实现该函数, 其中 LZCNT 花费的 CPU 周期更短, 因此需
要增加-mlzcnt 参数启用 LZCNT 指令.
表 4 平均执行时间与最大 RSS 的归一化几何平均数
AMD Ryzen 3700x Snapdragon 888+
内存分配器 版本
执行时间 RSS 执行时间 RSS
sys 2.34 1.292 0.978 1.566 1.060
tlsf - 16.125 0.694 9.284 0.824
tc gperftools-2.9.1 1.545 1.095 1.362 1.322
je 5.2.1 1.170 1.029 1.259 1.174
hd 5afe855 1.280 1.302 1.340 1.445
tbb 883c2e5 1.313 0.994 1.570 1.076
sn 0.5.3 0.869 1.121 0.889 1.244
mi v1.7.3 0.827 1.028 0.910 1.162
tlsfcc - 9.119 0.757 5.854 0.830
hslab - 1.075 1.035 1.157 1.148
wfslab - 1.000 1.000 1.000 1.000
wfslabfl - 1.005 0.993 0.994 1.004
wfslabm - 1.002 0.993 1.006 1.002
scudo ed56007 2.463 0.967 2.856 1.091
smi v1.7.3 1.057 1.271 1.294 1.334
mng 2ed5881 11.206 0.688 7.649 0.773
dh 1d08836 30.294 1.228 30.063 1.485
wfslabs - 1.135 1.106 1.340 1.102
hslabd - 1.200 1.162 1.283 1.266
tlsfccsd - 10.066 0.841 7.736 1.068
为验证榫卯框架本身的开销, 本文选取 wfslab 作为基准, 将该分配器算法手动编码实现为 wfslabm 分配器,
wfslabm 各项参数均与 wfslab 保持一致, 通过对比 wfslab 和 wfslabm 性能可得出使用榫卯框架搭建内存分配器的
开销. 同时, 为了进一步证明榫卯框架生成中间函数的开销可以被编译器优化消除, 本文编写了一个 fake 附加层
进行验证. 该附加层在判断内存请求大小后, 无论判断条件是否成立均将请求转交给下一层. 对于这种实质上不改
变分配器行为的额外层级, C 编译器优化机制会消除无意义的判断和额外的函数调用. 为了验证这一点, 本文使用
该附加层搭建了内存分配器 wfslabfl 进行对比, 该分配器在 wfslab 的每一个非系统接口层之上额外连接一个
fake 附加层.
此外, 本文为 wfslab, hslab 和 tlsfcc 增加了额外的安全附加层函数, 分别命名为 wfslabs, hslabd 和 tlsfccsd. 其
中 wfslabs 增加了一个使用异或校验策略的内存块尾部校验层 tail_chksum(chk_sum=xor, err_handle=default), 用于
检测缓冲区溢出, 异或校验和大小为 8 字节, 使用默认的错误处理策略: 只输出错误但不终止程序. hslabd 增加了