使用符合 CKB 虛擬機當前系統架構的真實 CPU 指令集來構建自己的虛擬機

Nervos 底層公鏈 CKB 的虛擬機(CKB-VM)是基於 RISC-V 打造的區塊鏈虛擬機。在前兩期中,我們介紹了 CKB 虛擬機的設計理念,以及基於 RISC-V 指令集打造的選擇邏輯。那麼再往前推一步,我們爲什麼會選擇基於真實 CPU 指令集來構建 CKB-VM 呢?在本篇文章中,CKB-VM 設計者將和我們繼續討論 CKB-VM 的設計靈感、設計以及基於真實 CPU 指令集來構建 CKB-VM 的額外優勢。

祕猿科技區塊鏈小課堂第 24 期


靈感與設計

image

在設計 CKB-VM 之前,我們發現很多區塊鏈項目並不是用真實的 CPU 指令集來構造自己的虛擬機。我們熟知的以太坊下一代虛擬機 EWASM、EOS 以及 Dfinity 等都選擇了 WASM(WebAssembly,一種編碼格式)來構造自己的虛擬機。我們也完全可以設計出一個具有高級語言特性的 VM,比如可以用於靜態驗證,或是可以直接支持高級數據結構,或是支持各種加密算法的 VM。

但是我們發現,雖然帶有高級語言特性的虛擬機能夠提供更多的便利,比如能夠支持語法各異的編程語言,但同時也會出現其他一些問題:任何複雜的、帶有高級語言功能的 VM,無論多麼靈活,都不可避免的會在設計層面引入一些語義約束,出於性能的原因,不同的語言在底層幾乎需要共享相同的語義(帶有高級語言特性的虛擬機需要綁定密碼學原語,若未來現有的原語被攻破,或者需要更換一套密碼學原語時,需要通過分叉來實現)。這樣一來, VM 自身的靈活性就會受到限制,這和 CKB 作爲加密經濟底層基礎設施的願景並不相符。

與此同時,一個帶有高級語言功能的 VM 通常會包含某些高級的數據結構與算法,這樣任何在 VM 中嵌入的高級數據結構與算法都可能只適合於某一類應用的開發,卻不適用於其它應用程序的開發。並且,我們無法預設所有可能的使用方式,這些嵌入 VM 本身的數據結構或算法除了兼容性之外沒有任何作用,隨着時間的推移,甚至會成爲負擔。

另外我們還發現,所有的區塊鏈項目都要在馮·諾伊曼 CPU 架構(x86,x86_64,ARM 等架構)下才能運行,並且所有高級的 VM 特性都必須映射到現代體系架構的 CPU 彙編指令。

舉個例子,雖然 V8 引擎(由 Google 開發的開源 JavaScript 引擎,用於 Google Chrome 及 Chromium 中)看上去可以有無限量的內存,但是其內部實現依然需要依靠一個十分複雜的垃圾回收算法,才能在有限的內存空間中模擬出無限的內存空間。

類似的,Haskell (一種標準化的,通用的純函數編程語言)或是 Idris(一個通用的依賴類型純函數式編程語言) 可能具有先進的靜態類型檢查模式(在某種程度上)來證明軟件運行的正確性,但在完成類型檢查之後,還是需要通過一個翻譯層把靜態驗證後的代碼轉換成未驗證的原生 x86_64 彙編指令。

這裏的關鍵在於無論我們如何設計 VM,都沒有辦法太過偏離當前的體系結構。換句話說,在任何 VM 的最底層,都需要將操作轉變成原始的彙編指令來執行。

於是我們想: 爲什麼不使用符合 CKB 虛擬機當前系統架構的真實 CPU 指令集來構建自己的虛擬機?

這樣一來,我們不會丟失任何添加靜態驗證、高級數據結構、或是加密算法的可能性,並且無論我們在 VM 中提供怎樣的數據結構或算法,都可以 最大化 VM 的靈活性 。此外,通過真實的 CPU 指令集,我們可以最大限度的讓開發者寫出任何滿足要求的合約。

額外的優勢

除了 靈活性 之外,基於真實 CPU 指令集的 VM 還有其它額外的優勢:

  • 穩定性

爲硬件設計的 CPU 指令集一旦最終確定並在芯片中使用,就難以修改,所以與通常是軟件實現的 VM 指令集相比,硬件指令集顯得非常穩定。這個屬性與 Layer 1 區塊鏈 VM 的訴求非常契合,因爲穩定的指令集意味着較少的硬分叉,且不會犧牲靈活性。

  • 運行期透明性

物理 CPU 在運行時僅需要依靠寄存器和一段內存,在使用堆棧的操作過程中,通常內存中的空間是指定的。這樣一來,我們可以在程序執行期間根據 VM 中的堆棧指針來獲取堆棧空間的使用情況,從而最大限度地提高運行時狀態的可見性。

CKB-VM 可以調整堆棧指針、更改內存中的區域分配,甚至根據需要擴大或縮小堆棧區域大小,從而提高 VM 的靈活性。當前 CPU 指令集還可以提供過去週期的計數,從而允許查詢 VM 的運行開銷狀態。

  • 運行期開銷

具有真實 CPU 指令集的 VM 可以輕鬆管理運行期的開銷,每個指令執行時所需的 cycle 數(不考慮流水線)是固定的。 我們可以根據真實 CPU 指令集的這個特性來設計 CKB-VM 運行時的開銷計算機制,這樣一來,當我們應用新算法時,也可以準確地計算出所需的開銷。

但是,與通過操作碼或本機 VM 指令集實現加密算法的 VM 相比,使用真實 CPU 指令集存在一個關鍵的缺點: 性能 。

不過,根據研究和測試結果,我們可以通過適當的優化和即時(Just-In-Time,JIT)編譯器實現來優化基於真實 CPU 指令集在 VM 上運行的加密算法,從而滿足 CKB 應用程序的需求。在處理即時性時,我們是基於底層指令集進行處理,而不是基於像 JavaScript 這樣的高級語言上處理,這樣會使得 VM 具備更低的工作負載和更好的性能。

Why Not WASM?

也許有人會問:在區塊鏈社區對 WebAssembly 有着強烈興趣和廣泛關注的情況下, CKB 爲什麼不直接使用 WebAssembly 呢?

WebAssembly 是一個偉大的項目,並且我們非常希望它最後能夠成功。一個擁有廣泛支持的沙盒環境,對於整個區塊鏈行業,甚至整個軟件業來說都是件夢寐以求的事。從長遠來看,WebAssembly 也有潛力實現 CKB 所需的大部分特性,但是它並不能提供我們在《CKB-VM 誕生記(一) 1》中提到的 RISC-V 能爲 CKB-VM 帶來的所有好處,比如,目前 WebAssembly 還全都是 JIT 實現,缺少一個合理的運行期開銷計算模型。

另外,RISC-V 從 2010 年開始設計,在 2011 年發佈第一版規範,2012 年出現基於 RISC-V 構建的硬件;而 WebAssembly 出現於 2015 年,2017 年發佈 MVP,相對來說,RISC-V 會比 WebAssembly 更加的成熟,所以至少在目前階段,我們覺得使用 WebAssembly 並不是 CKB-VM 最好的選擇。

當然,我們並不是完全放棄使用 WebAssembly,考慮到 WebAssembly 與 RISC-V 同樣是底層 VM 的實現方式,而且很多設計和指令集十分相似, 我們完全有可能提供一個從 WebAssembly 到 RISC-V 的二進制轉換器,從而確保 CKB 也可以利用目前區塊鏈上基於 WebAssembly 的創新。 另外,CKB 上也能夠支持僅可以編譯爲 WebAssembly 的語言(比如 Forest:https://github.com/forest-lan... )。

社區驅動的 CKB-VM

通過 CKB-VM 的設計,我們的目標是建立一個圍繞 CKB 的社區,該社區可以自由地發展和適應新技術的進步,並且可以最大限度地減少人工干預(例如硬分叉)。 我們相信 CKB-VM 可以實現這一願景。

注: CKB-VM 與 CKB 一樣爲開源項目,目前 CKB-VM 仍在開發過程中,儘管 CKB-VM 的大部分設計已經敲定,但某些設計也可能會在將來,因爲你的貢獻而有新的變動和推進。這篇文章是爲了讓我們的社區更加了解 CKB-VM,這樣人人都可以在裏面更好的玩耍並做出貢獻啦!

CKB-VM:https://github.com/nervosnetw...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章