Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify the goals/aims of this project | 讨论并明确项目的目标 #46

Open
inkydragon opened this issue Jan 5, 2025 · 2 comments

Comments

@inkydragon
Copy link

inkydragon commented Jan 5, 2025

背景/上下文

我看了 Readme 然后发现并没有 libm 也就是 math.h 数学库相关的部分。
想了一些数学库实现相关的具体问题,我的感觉是 mlibc 项目的目标不太清晰,我读完之后还是有疑问。
因此打开这个 issue 讨论并明确想项目的目标。

关于 libm 部分的具体疑问

一些疑问:
(这个issue并不是来专门讨论这些问题的具体答案的,提出这些疑问是为了引发后续的讨论。当然我也很高兴能获得这些问题的答案)

  1. 完整的 libc 肯定是包含数学库以及浮点数环境的,目前 mlibc 还没有开始,这是否在路线图上?
    或者说libc各个部分的开发优先级是什么?
  2. C 语言由对应的标准,libc 通常会遵循他们, mlibc 准备使用哪个版本, C99, C11, C23?。
    具体到数学库来说,使用不同的版本需要实现的 API 也有所不同。
    我大概会建议 C11;C99有点旧了;C23 加了不少新的数学函数,其他 libc 也在实现中。

项目期望里提到了“为小资源系统设计”和“针对risc-v 32/64进行优化”。
我理解前一点是需要限制编译后生成的代码的大小,后一点暗示会使用结构特定的汇编进行优化。
具体到数学库上,是性能优先还是可移植性优先?

  1. "精度 - 性能 - 可移植性" 的优先级是怎么样的?

    • 性能 - 可移植性:使用标准 C 并避免使用汇编,这样可移植性就高。
      反之使用具体平台的汇编,或者特定编译器的内部函数以提高性能
    • 精度 - 二进制大小:主要涉及打表的问题,float64 的实现有很多是一个巨大的表驱动;或者是实现自己的 float128
    • 精度 - 性能:如果不是要求特别高的精度,这两点的平衡相对好处理:
      确定精度目标 0.5eps 还是 < 1eps,然后尽力优化性能。
  2. 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 来说)。
    例如:

关于项目目标的讨论

现在主页上的“期望”是

mlibc/README_zh.md

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 提供比系统更好的实现。

一些可供讨论的问题

既然是讨论,我就多提出一些可以讨论的点,并提供我的观点抛砖引玉。
或许不一定能在短时间内达成共识,但至少指出了潜在的问题,提供了一个讨论的起点。

  1. 是出于什么原因/动机开发的 mlibc,或者说其他现有的 libc 有哪些问题,mlibc 又解决了哪些问题
  2. mlibc 是否打算实现完整的 libc,或者实现哪些子集,是否遵守 C 标准。
    鉴于 mlibc 已经明确提及针对于嵌入式目标,那么有些部分或许优先级会变低,或者干脆不提供实现。
    例如:https://github.com/embeddedartistry/libc 明确表示:“不提供完整的 C 标准库实现。相反,我们选择了对裸机嵌入式系统有用的函数子集。malloc 和 free 不包含在此库中”
    • 内存分配函数是否打算自行实现?这也是 musl 的弱点,一般会替换为其他的 malloc 库
    • libm 呢
    • locale.h, time.h
  3. 一个简单的 路线图/计划。
    比如:近期目标以能编译 XXXX 为主,优先实现需要的函数
  4. "为小资源系统设计" 具体是有多小,完整编译后 .a/.so 在什么量级?
    参考外部链接 1,musl 大概是 500k 的量级,而 glibc 是 2~8 MB 的量级
  5. 精确性 - 实现复杂度(或许还包含代码的可读性)
    举例:浮点数的准确打印,至少你 printf/strtof 的组合能够自洽。
    但精确的浮点打印或许需要 https://github.com/ulfjack/ryu ,大部分编程语言选择移植 ryu 或性能更高但更复杂的实现。
    当然嵌入式平台可以舍弃一些一致性/精度以换取实现的简单+更小的资源消耗
  6. 性能 - 可移植性
    我建议:目前以功能的正确性、完整性为主,暂时不考虑性能。
    可移植性明确偏向于 RiscV,即接受 RV 的汇编实现以提高性能,其他架构共享纯 C 的实现。
  7. 对贡献的要求。
    例如:是否接受相同许可证的代码移植,或者是兼容许可证的(MIT-Apache2)。或者要求重新编写干净的实现。
  8. 打算支持的平台和架构。目前的期望里提到了 RV 和裸机。
    那是否接受 x86_64 的支持,龙芯呢?
    我的建议:同第5点,除了必要的平台特定的汇编外(如 CRT0),实现一般是可移植的纯 C,短期内仅允许对 RV 平台的汇编级别优化
  9. 支持的编译器,目前明确提到 gcc 系,LLVM 只是在“甚至”中。
    一个现实的问题,当为此项目添加 CI 时,是否应该加入 clang。
    是否打算支持其他的嵌入式工具链,如 SDCC
  10. 或许可以和同类的嵌入式 libc 进行简要的比较,以突出 mlibc 的目标
  11. 欢迎补充

外部链接

  1. Comparison of C/POSIX standard library implementations for Linux
    经常被引用的 libc 实现比较,但数据应该很久没更新了,仅供参考。另外可以提供一些libc实现中可能的取舍点。
  2. C Library - OSDev Wiki
    一些开源的 libc 实现的比较
  3. A tale of two libcs
    这篇博客比较了 musl 和 glibc 关于 isalnum 函数实现的可读性比较。
  4. musl - Roadmap
    musl 的开发路线图,其中的 Open future goals 约等于 libc 中棘手的部分

一些协议友好的 libc

@BernardXiong
Copy link
Collaborator

👋 欢迎关注到mlibc

  • 不得不说,对于原本的mlibc来说,并没有考虑到太多的libm的部分,但如果有一套高质量的libm会非常欢迎;
    • 另外,libm应该在最终构建的时候是独立的libm.a,所以具体是否涉及到尺寸的问题,个人觉得关系目前不那么大;
  • mlibc的动机是为深度嵌入式系统考虑、逐步的,主因是newlib尺寸太大了 <当然目前mlibc vs newlib在有限资源的API占用上来说,似乎优势还不大>;
  • mlibc为深度嵌入式系统考虑,所以在helloworld例程目录下有不同平台的示例,当然也就粗略可以获得最终build出来的尺寸大小<因为API使用、验证并不完备,所以是粗略的>;
  • 深度嵌入式系统,比较典型的配置应该是:
    • 64kB Flash
    • 8kB/20kB SRAM
    • 例如青稞RISCV通用MCU CH32V103 系列
  • 许可证方面,MIT-Apache2兼容性许可证即可(不同的地方可以独立列出许可证情况),非常热烈欢迎贡献👋
  • 支持平台方面,优选RISCV、ARM、x86,当然其他平台也欢迎;
  • 暂时不考虑支持到SDCC,主要面向32位、64位MCU,而不是8位芯片;
  • 和其他libc的比较上,在计划中,不过可能需要先把mlibc做一定的完善和优化(包括资源占用的优化)

@BernardXiong
Copy link
Collaborator

从后续Roadmap来看,会考虑到以下几个阶段(及对应的feature规划,目前主要还处于拍脑袋阶段 😄 )

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants