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 都沒有。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。