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              增加了
   506   507   508   509   510   511   512   513   514   515   516