LemonHX

LemonHX

CEO of Limit-LAB 喜欢鼓捣底层的代码,意图改变世界
twitter
tg_channel

没有银弹: LemonVM设计缺陷反省, 以及对未来的展望.

image.png

缘起#

我在写 LemonVM 的时候,第一版采取的 Rust 语言,当时想着使用 Rust 语言至少能够保证在写 VM 的时候至少是内存安全的,
但是事实告诉我,在写这种层面的底层大项目的时候,想要使用静态检查来保证内存安全是不可能的一件事,尤其是我要写
垃圾回收的前提下,是不可能保证内存的占用是可以被估算的,所以我的代码充满了 Unsafe, 也丧失了 Rust 的最大优点之一 -- 内存安全

随后,因为指令集设计失误和过于画大饼,导致第一版 LemonVM 根本无法达到可用阶段,同时因为在我本地的源码已经达到了惊人的 1w 行的水平,所以我觉得好好重新设计一下,所以开始了第二版的征程.

再来一遍#

在第二版开始之后,大幅度的重构了原来的指令集和字节码加载部分,因为第一版借鉴的 LUA 的 VM, 然而 LUA 的 VM 由于 LUA 语言是
非常非常小的缘故,VM 的功能比较少,同时特别的 Trivial, 不能胜任复杂的工作,于是第二版直接开始借鉴 JVM, 但是由于 JVM 是基于栈的字节码而不是基于寄存器的字节码,于是我一遍借鉴 Dalvik 版的执行和 JVM 的加载模型,做出了第二版.

通过 @HoshinoTented 和我的示例程序,发现 LemonVM 第二版的效率在 Python 的 50x 的水准,这意味着肯定是哪里的开销过于巨大了,通过查找,我发现是我在实现的时候大量的使用了堆分配内存和 GC 的实现过于 Naive 导致的,同时还有 Rust Iter 和 Rust 的 Match 对 CPU 的分支预测起到了非常大的影响导致运行效率奇低无比,优化的方法有

  • 重写所有指令的实现
  • 所有堆分配手动管理
  • 避免使用 Rust 的 STD
  • 更精细的控制分支流程

第一个因为现在是 Prototype 阶段,所以可以跳过,第二个在 Rust 上近乎不可能,第三个同样,第四个由于 Rust 没有 Goto 和 Label as Var 所以根本就不能控制分支预测,也不能去手动优化指令的派发.

柠檬上头了#

于是柠檬开始 重新设计 重新设计 , 这回直接采用 C 语言作为开发语言,的确这四个问题都迎刃而解了,但是遇到了更大的问题,开发效率低的离谱,同时对于性能不敏感的 Use case 因为 C 没有 STD, 所以我需要自己实现 HashTable Vector 等这种最基础的数据结构,这个使得我的工作变得异常的缓慢,还有一个就是 C 的构建工具简直… 恶心,同时开了扩展就意味着在某些垃圾 MSVC 上面无法编译,这就丢失掉了我跨平台的初衷,我感到非常的难受,所以最近在尝试一种新的解决方案,首先使用 Rust 做完性能不敏感但是高度依赖标准库的 (比如字节码的加载,GC, 线程池等), 然后使用 C 语言去写核心逻辑的优化 (比如指令的分发,CPU 的分支预测优化,寄存器映射,栈映射等), 因为在 X64 模式下的 Rust 拿 ASM! 去写 MOVABSQ 还要看编译器脸色我真的做不到.


对未来底层编程语言的展望#

冰冰今天兴奋的跟我说,作为底层编程语言就必须有 goto 啊,lebel 啊,我现在为止都非常统一,但是作为高层语言,就必须有很高级的抽象,这些抽象有可能会破坏语言的底层特性,然后我和冰冰都注意到 F * 语言使用 lattice 来把语言通过割裂成不同的部分来进行底层操作,使得我们获得了很大的启发.

Unsafe Rust is NOT UNSAFE enough, Safe Rust is NOT SAFE enough

所以,希望未来能够推出一种语言,能够可控的调节使用多么底层的特性,而不是像 C 艹一样看编译器脸色,更不是学 Rust 搞了个不伦不类的 Unsafe 结果连 GOTO 都没有.

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。