-
Notifications
You must be signed in to change notification settings - Fork 14
Description
背景/上下文
我看了 Readme 然后发现并没有 libm 也就是 math.h 数学库相关的部分。
想了一些数学库实现相关的具体问题,我的感觉是 mlibc 项目的目标不太清晰,我读完之后还是有疑问。
因此打开这个 issue 讨论并明确想项目的目标。
关于 libm 部分的具体疑问
一些疑问:
(这个issue并不是来专门讨论这些问题的具体答案的,提出这些疑问是为了引发后续的讨论。当然我也很高兴能获得这些问题的答案)
- 完整的 libc 肯定是包含数学库以及浮点数环境的,目前 mlibc 还没有开始,这是否在路线图上?
或者说libc各个部分的开发优先级是什么? - C 语言由对应的标准,libc 通常会遵循他们, mlibc 准备使用哪个版本, C99, C11, C23?。
具体到数学库来说,使用不同的版本需要实现的 API 也有所不同。
我大概会建议 C11;C99有点旧了;C23 加了不少新的数学函数,其他 libc 也在实现中。
项目期望里提到了“为小资源系统设计”和“针对risc-v 32/64进行优化”。
我理解前一点是需要限制编译后生成的代码的大小,后一点暗示会使用结构特定的汇编进行优化。
具体到数学库上,是性能优先还是可移植性优先?
-
"精度 - 性能 - 可移植性" 的优先级是怎么样的?
- 性能 - 可移植性:使用标准 C 并避免使用汇编,这样可移植性就高。
反之使用具体平台的汇编,或者特定编译器的内部函数以提高性能 - 精度 - 二进制大小:主要涉及打表的问题,float64 的实现有很多是一个巨大的表驱动;或者是实现自己的 float128
- 精度 - 性能:如果不是要求特别高的精度,这两点的平衡相对好处理:
确定精度目标 0.5eps 还是 < 1eps,然后尽力优化性能。
- 性能 - 可移植性:使用标准 C 并避免使用汇编,这样可移植性就高。
-
mlibc 使用的是 MIT,那么是否介意直接移植现有的 libm 实现,然后再进行优化?
比如 musl-libc;或同为 MIT 的 https://github.com/JuliaMath/openlibm ;
抑或是精确舍入的 CORE-MATH (MIT) https://core-math.gitlabpages.inria.fr
题外话:关于我的动机
我是 julia,openlibm 的维护者之一,最近我还在为 openlibm 添加龙芯的 CI 构建及测试支持。
JuliaMath/openlibm#313
但最近也是我在推动从 julia 中移除对 openlibm 的依赖。
JuliaLang/julia#56875
(移除 openlibm 不是由我发起的,经过了很多尝试。我这次的尝试能成功构建并通过测试,离合并不远了)
因为系统提供的 libm 已经足够好了,openlibm 已经完成了它最初的目标。
等将 openlibm 从 julia 移除之后,我大概会在 openlibm 上打开一个 issue 讨论一下项目的后续计划,
因为项目的最大(?大概)用户没了,进一步开发的动力就小了许多,当然保持现状继续维护是没有问题的。
我的一个私心是:
- 如果 mlibc 不介意使用现有的代码,那么我推荐直接引入 openlibm
- 我近期的开发计划:使用 musl 的libm测试集,提高代码覆盖率;逐步合并入 core-math 的正确舍入实现
- 如果认为 openlibm 的代码来源复杂,则可以尝试移植 core-math,MIT 协议,从头编写。
对于版权或实现有任何疑问都可以联系作者,他在在开源社区很活跃,你在 openlibm 的 issue 里也能看见他。
据我观察 core-math 正在逐渐合并入各种 libc,包括但不限于 glibc,llvm-libc - 当然如果希望完全重新编写并消除任何潜在的版权隐患,
那么我建议使用最新的 libm 构建/生成技术来重新开发(新旧相对于 fdlibm 来说)。
例如:- IanBriggs/megalibm
对应的论文: Implementation and Synthesis of Math Library Functions | Proceedings of the ACM on Programming Languages - rutgers-apl/rlibm-32: RLibm for 32-bit representations (float and posit32)
- 还有一些新的技术可以在精度-性能-代码大小间进行平衡。这种选项我只在商业 libm 中见到过。也许是时候尝试一下了
- IanBriggs/megalibm
关于项目目标的讨论
现在主页上的“期望”是
Lines 39 to 49 in 39a1341
| ### 我们的期望 | |
| ● mlibc可以支持到多种嵌入式工具链,能够使用gcc(arm/risc-v)、甚至LLVM等编译器 | |
| ● 为小资源系统设计,完美地支持到一些嵌入式实时操作系统(RT-Thread等)和裸机 | |
| ● 针对risc-v 32/64进行优化,能够适配主流的一些RISC-V MCU | |
| ● 采用xmake和scons构建 | |
| ● reserve |
我用 openlibm 的目标作为对比:
OpenLibm is an effort to have a high quality, portable, standalone C mathematical library (libm). It can be used standalone in applications and programming language implementations.
The project was born out of a need to have a good libm for the Julia programming language that worked consistently across compilers and operating systems, and in 32-bit and 64-bit environments.
小结一下
- 项目范围限定:openlibm 专注于 libm 也就是数学库函数
- 可移植性:项目是 portable 可移植的,因此不使用平台相关的汇编
- 精度(速度):high quality 关心精度,这里没有明确提到速度的问题
- 支持的平台/工具链:支持多个编译器、平台架构
- 项目大的目标(起因):明确提到 openlibm 为 Julia 服务。
展开说是部分平台上系统 libm 有问题(msvcrt / win),使用 openlibm 提供比系统更好的实现。
一些可供讨论的问题
既然是讨论,我就多提出一些可以讨论的点,并提供我的观点抛砖引玉。
或许不一定能在短时间内达成共识,但至少指出了潜在的问题,提供了一个讨论的起点。
- 是出于什么原因/动机开发的 mlibc,或者说其他现有的 libc 有哪些问题,mlibc 又解决了哪些问题
- mlibc 是否打算实现完整的 libc,或者实现哪些子集,是否遵守 C 标准。
鉴于 mlibc 已经明确提及针对于嵌入式目标,那么有些部分或许优先级会变低,或者干脆不提供实现。
例如:https://github.com/embeddedartistry/libc 明确表示:“不提供完整的 C 标准库实现。相反,我们选择了对裸机嵌入式系统有用的函数子集。malloc 和 free 不包含在此库中”- 内存分配函数是否打算自行实现?这也是 musl 的弱点,一般会替换为其他的 malloc 库
- libm 呢
locale.h,time.h
- 一个简单的 路线图/计划。
比如:近期目标以能编译 XXXX 为主,优先实现需要的函数 - "为小资源系统设计" 具体是有多小,完整编译后 .a/.so 在什么量级?
参考外部链接 1,musl 大概是 500k 的量级,而 glibc 是 2~8 MB 的量级 - 精确性 - 实现复杂度(或许还包含代码的可读性)
举例:浮点数的准确打印,至少你 printf/strtof 的组合能够自洽。
但精确的浮点打印或许需要 https://github.com/ulfjack/ryu ,大部分编程语言选择移植 ryu 或性能更高但更复杂的实现。
当然嵌入式平台可以舍弃一些一致性/精度以换取实现的简单+更小的资源消耗 - 性能 - 可移植性
我建议:目前以功能的正确性、完整性为主,暂时不考虑性能。
可移植性明确偏向于 RiscV,即接受 RV 的汇编实现以提高性能,其他架构共享纯 C 的实现。 - 对贡献的要求。
例如:是否接受相同许可证的代码移植,或者是兼容许可证的(MIT-Apache2)。或者要求重新编写干净的实现。 - 打算支持的平台和架构。目前的期望里提到了 RV 和裸机。
那是否接受 x86_64 的支持,龙芯呢?
我的建议:同第5点,除了必要的平台特定的汇编外(如 CRT0),实现一般是可移植的纯 C,短期内仅允许对 RV 平台的汇编级别优化 - 支持的编译器,目前明确提到 gcc 系,LLVM 只是在“甚至”中。
一个现实的问题,当为此项目添加 CI 时,是否应该加入 clang。
是否打算支持其他的嵌入式工具链,如 SDCC - 或许可以和同类的嵌入式 libc 进行简要的比较,以突出 mlibc 的目标
- 欢迎补充
外部链接
- Comparison of C/POSIX standard library implementations for Linux
经常被引用的 libc 实现比较,但数据应该很久没更新了,仅供参考。另外可以提供一些libc实现中可能的取舍点。 - C Library - OSDev Wiki
一些开源的 libc 实现的比较 - A tale of two libcs
这篇博客比较了 musl 和 glibc 关于 isalnum 函数实现的可读性比较。 - musl - Roadmap
musl 的开发路线图,其中的 Open future goals 约等于 libc 中棘手的部分
一些协议友好的 libc
- [MIT] musl
https://musl.libc.org/ - [MIT] mlibc - Portable C standard library
https://github.com/managarm/mlibc - [MIT] embeddedartistry/libc
https://github.com/embeddedartistry/libc - [CC0] PDCLib - Public Domain C Library
https://github.com/DevSolar/pdclib - [MIT] PDPCLIB - Public Domain Project C Runtime Library
https://www.pdos.org/