近期,RISC-V SIG 在欧拉嵌入式操作系统上成功实现了 musl libc 的适配,完成了使用 musl libc 库替换 glibc 库构建镜像的工作。目前,以 musl libc 为基础库编译的镜像已在 Raspberry Pi4 开发板上可用,这一成果推动了 openEuler Embedded 的多态发展。
编译镜像步骤说明:
https://openeuler.gitee.io/yocto-meta-openeuler/master/features/muslc.html
Musl libc 库对比 glibc 库的部分优点
- 它是一个专门为嵌入式系统开发的轻量级 libc 库,以简单、轻量和高效为特色;
- musl libc 要小得多,因为 musl libc 专注于尽可能减少代码大小和函数调用开销,以提高性能;
- musl libc 库的源码相对简单,封装性不强,不像 glibc 的代码一样臃肿,复杂;
- musl libc 是 C 语言的一种标准函数库,代码干净且高效,针对静态连接(static linking)设计,适合被用来制作可携的程序,且也很容易进行交叉编译(cross compile),编译出运行在不同系统环境的程序。
Musl libc 库对比 glibc 库的部分缺点
- POSIX 标准:musl libc 更加严格地遵循 POSIX 标准,而 glibc 则添加了一些扩展,以提供更多的功能和兼容性。
- 错误处理:musl libc 实现的错误处理更严格和更规范,而 glibc 则有更多的错误处理选项,并且支持不同的语言环境。
综上所述,如果你需要一个小巧且速度较快的 C 标准库在 Linux 系统上使用,则可以考虑使用 musl libc;如果你要开发的某个功能的可执行程序需要在不同系统环境下运行,则 musl libc 可满足你的需求;如果你想一次编译出可以在相同 CPU 架构的 Linux 发行版上都运行的程序,musl libc 库将是最优的选择,因为基于 glibc 库已编译好的函数库和运行档在不同的 Linux 上可能会出现无法共用的情况,。
Raspberry Pi 4:musl libc 与 glibc 性能等方面对比
Libc-bench 是 musl 官方提供的测试集,用于时间和内存效率的测试,该测试集中比较了各种 C/POSIX 标准库函数的实现。
UnixBench 是一款开源的测试 unix 系统基本性能的工具,测试系统各个方面的性能,然后将各测试结果和一个基准值进行比较,得到一个索引值,所有测试项目的索引值结合在一起形成一个测试分数值。这个测试分数越高代表此系统性能越好。
为了对比以 musl libc 与 glibc 为标准库的镜像在性能等方面差异,本次测试我们使用 libc-bench、Unixbench 工具对基于 musl libc 和 glibc 编译的树莓派镜像进行了测试,测试结果如下:
Libc-bench 进行内存占用率测试结果如下:
从上述测试输出结果可以得出以下结论:以 musl libc 为标准库编译的镜像在虚拟内存占用、物理内存占用、系统可回收内存方面都是远优于 glibc;
基于 musl libc 库的树莓派系统性能测试数据如下:
基 glibc 库的树莓派系统性能测试数据如下:
综上,基于 glibc 的树莓派系统跑分结果为 146.5 ,基于 musl libc 的树莓派系统跑分结果为 161.6 ;所以基于 musl libc 编译的树莓派镜像在性能上有大于 10%的提升;
进一步挖掘 musl libc 与 openEler Embedded 系统结合在性能和功能方面的潜力
当然,目前基于 musl libc 库编译的镜像在性能和功能方面还是有很大的提升空间。在性能方面,musl 库中 malloc 系列函数和 memcpy 系列函数实现较慢。尤其是 malloc 的性能,在多线程环境下会显著造成瓶颈,原因在于 musl libc 的 malloc 实现在每次 malloc 时都需要对全局变量加锁解锁, 导致严重的竞争现象,后续也需要在类似这方面上进行优化以便提高性能等;
在功能方面,musl libc 在字符集/编码方面的支持没有 glibc 全面;在错误处理方面,glibc 有更多的错误处理选项,并且支持不同的语言环境;POSIX 标准方面,glibc 添加了一些扩展,以提供更多的功能和兼容性等等,musl libc 库在不影响性能等前提下,在这上述能方面进行功能上的填充还是有很大的发掘空间的。