EVM多線程並行優化:解鎖Rollup性能瓶頸

EVM並行化優化:以Reddio爲例探討性能提升之路

衆所周知,EVM是以太坊最核心的組件之一,擔任着"執行引擎"和"智能合約運行環境"的重要角色。在區塊鏈這樣一個由成千上萬節點組成的開放網路中,不同節點的硬件配置可能有很大差異。爲了確保智能合約在各個節點上都能得到一致的執行結果,虛擬機技術成爲了理想的解決方案。

EVM能夠在不同操作系統和設備上以相同的方式運行智能合約,這種跨平台兼容性保證了每個節點執行合約後都能得到一致的結果。這與Java虛擬機JVM的原理類似。

我們在區塊瀏覽器中看到的智能合約,都是先被編譯爲EVM字節碼,然後存儲在鏈上。EVM執行合約時,會按順序讀取這些字節碼,每條指令都有相應的Gas成本。EVM會追蹤每條指令執行過程中的Gas消耗,消耗量取決於操作的復雜程度。

作爲以太坊的核心執行引擎,EVM採用串行方式處理交易,所有交易在單一隊列中排隊並按確定順序依次執行。之所以不採用並行化方式,是因爲區塊鏈需要嚴格保證一致性,同一批交易在所有節點中都要按相同順序處理。如果將交易處理並行化,很難精確預判交易順序,除非引入復雜的調度算法。

2014-2015年,以太坊創始團隊出於時間緊迫,選擇了設計簡單且易於維護的串行執行方式。然而,隨着區塊鏈技術的迭代和用戶羣體的擴大,對TPS和吞吐量的要求越來越高。在Rollup技術出現並成熟落地後,EVM串行執行帶來的性能瓶頸在以太坊二層網路上已經明顯暴露出來。

Sequencer作爲Layer2的關鍵組件,以單個服務器的形式承擔所有計算任務。如果與Sequencer配合的外部模塊效率都足夠高,最終的瓶頸將取決於Sequencer本身的效率,此時串行執行將成爲巨大障礙。

某團隊通過對DA層和數據讀寫模塊進行極致優化,使Sequencer每秒最多可執行約2000多筆ERC-20轉帳。這個數字看似很高,但如果要處理的交易比ERC-20轉帳復雜得多,TPS數值必然會大幅下降。因此,交易處理的並行化將是未來的必然趨勢。

以Reddio爲例,闡述並行EVM的優化之路

以太坊交易執行的兩大核心組件

除EVM外,go-ethereum中與交易執行相關的另一核心組件是stateDB,用於管理以太坊中的帳戶狀態和數據存儲。以太坊採用名爲Merkle Patricia Trie的樹狀結構作爲數據庫索引,EVM每次交易執行都會改變stateDB中存儲的某些數據,這些變更最終會反映在全局狀態樹中。

stateDB負責維護所有以太坊帳戶的狀態,包括EOA帳戶和合約帳戶,存儲的數據包括帳戶餘額、智能合約代碼等。在交易執行過程中,stateDB會對相應帳戶的數據進行讀寫。交易執行結束後,stateDB需要將新的狀態提交到底層數據庫中進行持久化處理。

總的來說,EVM負責解釋和執行智能合約指令,根據計算結果改變區塊鏈上的狀態,而stateDB則充當全局狀態存儲,管理所有帳戶和合約的狀態變化。兩者協作構建了以太坊的交易執行環境。

以Reddio爲例,闡述並行EVM的優化之路

串行執行的具體過程

以太坊的交易類型分爲EOA轉帳和合約交易。EOA轉帳是最簡單的交易類型,即普通帳戶之間的ETH轉帳,不涉及合約調用,處理速度很快,收取的gas費也很低。

合約交易則涉及智能合約的調用與執行。EVM處理合約交易時,需要逐條解釋和執行智能合約中的字節碼指令,合約邏輯越復雜,涉及的指令越多,消耗的資源也就越多。

例如,ERC-20轉帳的處理時間約爲EOA轉帳的2倍,而更復雜的智能合約,如某DEX上的交易操作,耗時可能是EOA轉帳的十幾倍。這是因爲DeFi協議在交易時需要處理流動性池、價格計算、代幣交換等復雜邏輯,需要進行大量計算。

在串行執行模式下,EVM與stateDB這兩個組件協作處理交易的過程如下:

以太坊設計中,一個區塊內的交易會按先後順序被逐筆處理,每筆交易都有一個獨立實例執行具體操作。盡管每筆交易使用不同的EVM實例,但所有交易共用同一個狀態數據庫stateDB。

交易執行過程中,EVM需要不斷與stateDB交互,從stateDB中讀取相關數據,並將變更後的數據寫回stateDB。

當一個區塊中所有交易都執行完畢後,stateDB中的數據會被提交到全局狀態樹,並生成新的狀態根。狀態根是每個區塊中的重要參數,記錄了區塊執行後新的全局狀態的"壓縮結果"。

EVM的串行執行模式瓶頸明顯:交易必須按順序排隊執行,如果出現耗時較長的智能合約交易,在其處理完畢前,其他交易只能等待,這顯然無法充分利用CPU等硬件資源,效率受到較大限制。

以Reddio爲例,闡述並行EVM的優化之路

EVM的多線程並行優化方案

串行執行與並行執行可以類比爲只有一個櫃臺的銀行和有多個櫃臺的銀行。並行模式下可以開啓多個線程同時處理多筆交易,效率可以得到幾倍提升,但棘手的是狀態衝突問題。

如果多筆交易都聲明要修改某個帳戶的數據,當它們被同時處理時,就會產生衝突。比如某NFT只能鑄造1個,而交易1和交易2都聲明要鑄造該NFT,如果兩個請求都得到滿足,顯然會出錯。實際操作中的狀態衝突往往更頻繁,所以並行化交易處理必須有應對狀態衝突的措施。

以Reddio爲例,闡述並行EVM的優化之路

Reddio對EVM的並行優化原理

某ZKRollup項目對EVM的並行優化思路是爲每個線程分配一筆交易,並在每個線程中提供一個臨時的狀態數據庫,稱爲pending-stateDB。具體細節如下:

  1. 多線程並行執行交易:設置多個線程同時處理不同的交易,線程之間互不幹擾。這可以幾倍提升交易處理速度。

  2. 爲每個線程分配臨時狀態數據庫:爲每個線程都分配一個獨立的臨時狀態數據庫(pending-stateDB)。各個線程執行交易時,不直接修改全局stateDB,而是將狀態變化結果暫時記錄在pending-stateDB中。

  3. 同步狀態變更:在一個區塊內的所有交易都執行完畢後,EVM會將每個pending-stateDB中記錄的狀態變更結果依次同步到全局stateDB中。如果不同交易在執行過程中沒有發生狀態衝突,就可以將pending-stateDB中的記錄順利合並到全局stateDB中。

以Reddio爲例,闡述並行EVM的優化之路

該項目對讀寫操作的處理方式進行了優化,以確保交易能夠正確訪問狀態數據並避免衝突:

  • 讀操作:當交易需要讀取狀態時,EVM首先檢查Pending-state的ReadSet。如果ReadSet存在所需數據,直接從pending-stateDB中讀取。如果ReadSet中沒有找到對應的鍵值對,就從上一個區塊對應的全局stateDB中讀取歷史狀態數據。

  • 寫操作:所有寫操作(即對狀態的修改)都不會直接寫入全局stateDB,而是先記錄到Pending-state的WriteSet中。待交易執行完成後,通過衝突檢測再嘗試將狀態變更結果合並到全局stateDB中。

以Reddio爲例,闡述並行EVM的優化之路

並行執行的關鍵問題在於狀態衝突,當多筆交易嘗試讀寫相同帳戶的狀態時,該問題尤爲顯著。爲此引入了衝突檢測機制:

  • 衝突檢測:在交易執行過程中,EVM會監測不同交易的ReadSet和WriteSet。如果發現多個交易嘗試讀寫相同的狀態項,則視爲發生衝突。

  • 衝突處理:當檢測到衝突時,衝突交易將被標記爲需要重新執行。

在所有交易都執行完成後,多個pending-stateDB中的變更記錄會被合並到全局stateDB中。如果合並成功,EVM會將最終狀態提交到全局狀態樹中,並生成新的狀態根。

以Reddio爲例,闡述並行EVM的優化之路

多線程並行優化對性能的提升是顯著的,特別是在處理復雜智能合約交易時。研究顯示,在低衝突工作負載(交易池中較少矛盾的或佔用相同資源的交易)中,基準測試的TPS相比傳統串行執行提升了3-5倍左右。在高衝突工作負載中,理論上如果將所有優化手段都用上,甚至可以達到60倍的提升。

以Reddio爲例,闡述並行EVM的優化之路

總結

該項目的EVM多線程並行優化方案,通過爲每個交易分配臨時狀態庫,並在不同線程中並行執行交易,顯著提高了EVM的交易處理能力。通過優化讀寫操作和引入衝突檢測機制,EVM系公鏈能夠在保證狀態一致性的前提下,實現交易的大規模並行化,解決了傳統串行執行模式帶來的性能瓶頸。這爲以太坊Rollup未來的發展奠定了重要基礎。

以Reddio爲例,闡述並行EVM的優化之路

ETH2.18%
查看原文
此頁面可能包含第三方內容,僅供參考(非陳述或保證),不應被視為 Gate 認可其觀點表述,也不得被視為財務或專業建議。詳見聲明
  • 讚賞
  • 5
  • 分享
留言
0/400
SocialFiQueenvip
· 08-05 12:02
是和鸿蒙有一拼了
回復0
SerumSquirtervip
· 08-05 00:36
reddio上号 快点干活
回復0
社恐质押者vip
· 08-03 20:27
多线程牛逼啊
回復0
链游脱坑专家vip
· 08-03 20:25
搞了这么久v1还是优化不太行啊
回復0
梭哈爸爸vip
· 08-03 20:00
reddio谁懂啊 就跟刀哥一样上岸
回復0
交易,隨時隨地
qrCode
掃碼下載 Gate APP
社群列表
繁體中文
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)