EVM并行化突破:Layer2性能提升60倍的关键技术

EVM并行化优化:突破性能瓶颈的关键

众所周知,EVM是以太坊最重要的核心组件之一,被定位为"执行引擎"和"智能合约执行环境"。由于公链是一个包含大量节点的开放网络,不同节点的硬件参数差异很大。为了让智能合约在多个节点上都能得到相同结果,满足"一致性"要求,虚拟机技术可以在不同设备上搭建相同的环境。

EVM能够在各种操作系统和设备上以相同方式运行智能合约,这种跨平台兼容性确保每个节点执行合约后都能得到一致结果。这与Java虚拟机JVM的原理类似。

我们在区块浏览器中看到的智能合约,都是先被编译为EVM字节码,然后存储到链上。EVM执行合约时,会按顺序读取这些字节码,每条指令都有相应的Gas成本。EVM会跟踪每条指令执行过程中的Gas消耗,消耗量取决于操作的复杂度。

以Reddio为例,阐述并行EVM的优化之路

作为以太坊的核心执行引擎,EVM采用串行方式处理交易,所有交易在单一队列中排队并按确定顺序执行。之所以不采用并行化方式,是因为区块链需要严格满足一致性,一批交易在所有节点中都要按相同顺序处理。如果将交易处理并行化,难以精确预判交易顺序,除非引入复杂的调度算法。

以太坊创始团队在2014-2015年出于时间紧迫,选择了设计简单且易于维护的串行执行方式。然而,随着区块链技术的迭代和用户群体扩大,对TPS和吞吐量的要求越来越高。在Rollup技术成熟后,EVM串行执行带来的性能瓶颈在以太坊二层网络中已经显露无疑。

Sequencer作为Layer2的关键组件,以单个服务器形式承担所有计算任务。如果与Sequencer配合的外部模块效率足够高,最终瓶颈将取决于Sequencer本身的效率,此时串行执行将成为巨大阻碍。

某团队通过对DA层和数据读写模块进行极致优化,使Sequencer每秒最多可执行约2000多笔ERC-20转账。这个数字看似很高,但如果处理的交易比ERC-20转账复杂得多,TPS数值必然会大幅下降。因此,交易处理的并行化将成为未来的必然趋势。

接下来,我们将深入探讨传统EVM的局限性,以及并行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。

从代码角度看,EVM和stateDB协作执行交易的大致流程如下:

  1. processBlock()函数调用Process()函数处理一个区块中的交易。

  2. Process()函数中定义了一个for循环,交易被逐笔执行。

  3. 所有交易处理完毕后,processBlock()函数调用writeBlockWithState()函数,再调用statedb.Commit()函数,提交状态变更结果。

当一个区块中所有交易执行完毕,stateDB中的数据会被提交到全局状态树,并生成新的状态根。状态根是每个区块中的重要参数,记录了区块执行后新的全局状态的"压缩结果"。

以Reddio为例,阐述并行EVM的优化之路

EVM的串行执行模式瓶颈明显:交易必须按顺序排队执行,如果出现耗时很长的智能合约交易,其他交易只能等待,无法充分利用CPU等硬件资源,效率受到较大限制。

EVM的多线程并行优化方案

将串行执行与并行执行进行类比,前者如同只有一个柜台的银行,而并行EVM则像有多个柜台的银行。并行模式下可以开启多个线程同时处理多笔交易,效率可以提升数倍,但面临的难题是状态冲突问题。

如果多笔交易都声明要修改某个账户的数据,同时处理时就会产生冲突。例如,某NFT只能铸造1个,而交易1和交易2都要铸造该NFT,如果两个请求都得到满足,显然会出错。实际操作中,状态冲突往往更频繁,因此并行化交易处理必须有应对状态冲突的措施。

以Reddio为例,阐述并行EVM的优化之路

某项目对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。

并行执行的关键问题是状态冲突,多笔交易尝试读写相同账户状态时尤为显著。为此引入了冲突检测机制:

冲突检测:交易执行过程中,EVM监测不同交易的ReadSet和WriteSet。如果发现多个交易尝试读写相同状态项,则视为发生冲突。

冲突处理:检测到冲突时,冲突交易被标记为需要重新执行。

所有交易执行完成后,多个pending-stateDB中的变更记录会合并到全局stateDB。如果合并成功,EVM将最终状态提交到全局状态树,并生成新的状态根。

以Reddio为例,阐述并行EVM的优化之路

多线程并行优化对性能提升显著,特别是处理复杂智能合约交易时。研究显示,在低冲突工作负载中,基准测试的TPS比传统串行执行提升了3-5倍。在高冲突工作负载中,理论上如果采用所有优化手段,甚至可达到60倍提升。

总结

上述EVM多线程并行优化方案,通过为每个交易分配临时状态库,并在不同线程中并行执行交易,显著提高了EVM的交易处理能力。通过优化读写操作和引入冲突检测机制,EVM系公链能够在保证状态一致性的前提下,实现交易的大规模并行化,解决了传统串行执行模式带来的性能瓶颈。这为以太坊Rollup未来的发展奠定了重要基础。

未来研究方向包括:进一步优化存储效率以提升性能,应对高冲突情况的优化方案,以及如何借助GPU进行优化等内容。

以Reddio为例,阐述并行EVM的优化之路

此页面可能包含第三方内容,仅供参考(非陈述/保证),不应被视为 Gate 认可其观点表述,也不得被视为财务或专业建议。详见声明
  • 赞赏
  • 5
  • 分享
评论
0/400
ForkItAllDayvip
· 23小时前
牛逼了以太坊
回复0
GateUser-3824aa38vip
· 07-11 18:27
性能提升太大了
回复0
wrekt_but_learningvip
· 07-11 18:23
大胆向前冲
回复0
MemeTokenGeniusvip
· 07-11 18:23
有点东西,很靠谱
回复0
WalletsWatchervip
· 07-11 18:13
性能提升很猛啊
回复0
交易,随时随地
qrCode
扫码下载 Gate APP
社群列表
简体中文
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)