Por Po, Qi Zhou
Agradecimentos especiais a Toni e Dragan pelo feedback e avaliação!
Resumo
Ethereum está escalando L1 aumentando gradualmente o limite de gás do bloco. No entanto, aumentar substancialmente o limite de gás (por exemplo, o aumento de 100x proposto por Dankrad) atinge rapidamente limites rígidos – E/S de disco e velocidade de execução da CPU. O pré-aquecimento e as listas de acesso em nível de bloco (BAL) EIP-7928 removem a maioria das paralisações de leitura de E/S, transferindo o gargalo principal para a execução em si. Enquanto isso, os clientes atuais ainda executam transações sequencialmente, limitando fundamentalmente o rendimento.
BAL (uma ideia que nossa equipe também explorou dois anos antes) desbloqueia a execução paralela perfeita, mas seu limite de desempenho permanece incerto. Para resolver esta questão, construímos um ambiente de execução pura com:
- estado pré-carregado, simulando um ambiente onde contas relevantes, slots de armazenamento e código de contrato são pré-resolvidos por meio de dicas BAL;
- remetente tx pré-recuperado, aproveitando a recuperação de remetente paralelo já implementada na maioria dos clientes;
- omissão da computação da raiz estatal, cujo custo pode ser amortizado para blocos maiores.
Usando esse ambiente, avaliamos a execução paralela por transação com BAL. Nossos resultados mostram que o rendimento de execução pura excede 10 GigaGás/s em um PC moderno de 16 núcleos, enquanto o cliente Reth atual atinge apenas cerca de 1,2 GigaGas/s nas mesmas condições. Isso indica que a execução do EVM pode escalar uma ordem de magnitude além das linhas de base atuais do cliente, uma vez que os gargalos mencionados acima sejam totalmente resolvidos.
Ethereum está aumentando seu limite de gás de 45 M para 60 M na atualização Fusaka. Suponha que o limite de gás fosse aumentado em 100x, o bloco resultante conteria aproximadamente 4,5 G de gás. Para manter o tempo de validação abaixo de três segundos, os validadores precisariam, portanto, de pelo menos 1,5 GigaGas/s de taxa de transferência de execução. No entanto, os benchmarks públicos da Base mostram que os clientes modernos em hardware comum atingem um máximo de apenas cerca de 600 MGas/s. Essa limitação se deve principalmente à execução sequencial: embora CPUs multinúcleos estejam disponíveis, os clientes existentes processam transações em série, deixando a maioria dos núcleos subutilizados.
| Carga útil de transmissão | Geth MGgas/s | Reth MGgas/s |
|---|---|---|
| simulação base-mainnet | 316,4 | 591,6 |
A lacuna entre o desempenho atual (~0,6 GGas/s) e o que o escalonamento de 100× requer (~1,5 GGas/s) ainda é substancial — o que motiva nosso impulso em direção à execução de EVM totalmente paralela.
Para estudar o desempenho final de execução paralela que o BAL traz, construímos um ambiente de execução pura removendo todas as partes não relacionadas de não execução, permitindo-nos medir o verdadeiro limite superior do paralelismo alimentado por BAL. Aproveitando o design sem GC do Rust, o controle refinado sobre o agendamento multithread e o alto desempenho do Reth, modificamos o cliente Reth e usamos o revm como mecanismo de execução EVM para este experimento.
Simplificação para Emulação de Execução Pura
- Todo o estado da cadeia é carregado na memória antecipadamente (já que podemos agrupar E/S de acordo com os locais de leitura do BAL).
- Todas as transações vêm com o remetente já recuperado (a recuperação do remetente pode ser totalmente paralelizada antecipadamente).
- Nenhum cálculo de raiz de estado e commits de banco de dados são realizados após a execução (é um gargalo, mas não é o foco principal deste estudo).
Trabalho e configuração de engenharia
- Modificado o cliente Reth para suportar o despejo de dependências de execução completas, incluindo blocos, BALs, os últimos 256 hashes de bloco e estados de pré-bloco resolvidos a partir de dicas de conjunto de leitura BAL.
- Adicionado um adaptador para Revm carregar
blockEnv,stateetxEnve para criar uma instância EVM separada por transação. - Granularidade do paralelismo = por transação.
- Hardware: AMD Ryzen 9 5950X (16 núcleos), 128 GB de RAM.
- Conjunto de dados: 2.000 blocos mainnet (
#23600500–23602500). - Métrica: Gás por segundo = total de gás usado/tempo de emulação de execução pura.
Conjunto de benchmark disponível aqui:
https://github.com/dajuguan/evm-benchmark
Nossa avaliação começou alinhando o desempenho sequencial com o revm e depois introduzindo progressivamente a execução paralela. A análise do escalonamento paralelo revelou que a latência das transações de maior duração constitui o caminho crítico que limita a aceleração geral. Para aliviar essa restrição, simulamos limites maiores de gás de bloco, o que desbloqueou um paralelismo substancial com o BAL. Com 16 threads e limite de gás de bloco de 1G, a taxa de transferência de execução pura foi alcançada ~14 GGas/s.
Alinhamento de linha de base com execução sequencial
Primeiro tentamos reproduzir os resultados do benchmark de Reth. Em uma execução sequencial em dados da rede principal com a configuração KZG pré-carregada, a execução pura atingiu 1.212 MGas/s.
Este resultado sequencial serve como ponto de referência para todos os experimentos seguintes.
Execução paralela e seus gargalos no caminho crítico
Para avaliar tanto a aceleração real quanto o efeito da lei de Amdahl no paralelismo no nível da transação, conduzimos experimentos de execução paralela por transação para quantificar o impacto das transações de maior duração na aceleração alcançável.
Os resultados detalhados são mostrados abaixo (onde “maior latência de txs” é o tempo total de execução das transações de maior duração em cada bloco):
| Tópicos | Taxa de transferência (MGas/s) | Latência de TX mais longa | Tempo total |
|---|---|---|---|
| 1 | 1.258 | 6,06s | 33,47s |
| 2 | 2.460 | 6,04s | 17,12s |
| 4 | 3.753 | 6,10s | 10,71s |
| 8 | 4.824 | 6h00 | 8,73s |
| 16 | 5.084 | 6,04s | 8,29s |
No geral, os resultados de escalonamento se alinham estreitamente com a lei de Amdahl: embora a taxa de transferência aumente com mais threads, o tempo de execução do bloco é limitado pela transação mais longa, que representa cerca de 70% do tempo total de execução em 16 threads, limitando a aceleração alcançável em aproximadamente 5× em vez dos 16× ideais para uma máquina de 16 núcleos. Isso indica que a escalabilidade é determinada por caminhos críticos por bloco, e não pela capacidade computacional bruta.
Essa limitação do caminho crítico pode ser mitigada reduzindo o domínio da transação mais longa, por exemplo, por meio do EIP-7825: limite de gás de transação ou aumentando o limite de gás de bloco – a abordagem explorada neste artigo.
7928 + Mega Blocos = Paralelismo Massivo
Como os caminhos críticos por bloco limitam a simultaneidade, experimentamos “megablocos” de maior gás para aumentar o paralelismo. Para simular isso, executamos as transações de vários blocos consecutivos da rede principal, ou seja, um megabloco ou um lote, em paralelo, e então confirmamos o estado (noop no experimento) somente após todas as transações no lote terem sido concluídas. Isso agrega efetivamente vários blocos em uma única unidade de execução grande.
Análise de paralelismo sob cargas de trabalho de megablocos
Primeiro avaliamos um lote de 50 blocos, simulando um uso médio de gás de bloco de 1.053 M, em diferentes contagens de threads. Os resultados completos são mostrados abaixo:
| Tópicos | Taxa de transferência (MGas/s) | Latência de TX mais longa | Tempo total |
|---|---|---|---|
| 1 | 1.440 | 0,50s | 29,26s |
| 2 | 2.793 | 0,50s | 15.08s |
| 4 | 5.167 | 0,52s | 8h15s |
| 8 | 9.095 | 0,54s | 4,63s |
| 16 | 14.001 | 0,59s | 3,01s |
Com blocos tão grandes, as transações de execução mais longa não dominam mais o caminho crítico – elas contribuem com menos de 20% do tempo total de execução em 16 threads. A taxa de transferência é escalonada quase linearmente com a contagem de threads: com 16 threads, alcançamos 14 GGAs/s, aproximadamente uma aceleração de 10x em relação à execução sequencial e perto da escala linear ideal. Isto é extremamente encorajador. Em nossos experimentos, o principal caminho crítico restante é o point_evaluation pré-compilação, que não é trivialmente paralelizável.
Rendimento sob diferentes usos de gás de bloco
Para avaliar como a execução paralela aumenta com o aumento do uso de gás de bloco, executamos lotes de blocos consecutivos enquanto variamos o tamanho do lote de bloco – o número de blocos agrupados em um único megabloco – simulando assim diferentes usos efetivos de gás de bloco.
| Tópicos | Tamanho do lote de blocos | Média Bloquear Gás (M) | Taxa de transferência (MGas/s) |
|---|---|---|---|
| 16 | 1 | 21 | 5.084 |
| 16 | 2 | 42 | 6.641 |
| 16 | 5 | 105 | 8.814 |
| 16 | 10 | 210 | 10.228 |
| 16 | 25 | 526 | 12.152 |
| 16 | 50 | 1.053 | 14.001 |
| 16 | 100 | 2.106 | 14.887 |
| 16 | 200 | 4.212 | 15.298 |
À medida que o uso do gás de bloco aumenta, o rendimento continua a aumentar, mas os ganhos incrementais de paralelismo diminuem de ~30% para ~3% para cada duplicação do gás de bloco. Uma vez que o tamanho do lote excede ~50 blocos (≈1.053M de gás de bloco), aumentos adicionais no gás de bloco produzem apenas uma produção adicional marginal.
Nossos experimentos mostram que a combinação EIP-7928 com megablocos permite que a execução da transação seja escalonada excepcionalmente bem, alcançando 14 GigaGas/s de rendimento de execução pura em um processador moderno de 16 núcleos. No entanto, várias questões em aberto permanecem:
1. Recuperação do remetente
Excluímos a recuperação do remetente do benchmark de execução pura. Em nosso experimento, habilitá-lo reduz o rendimento em aproximadamente 2/3, caindo para cerca de 5 GigaGas/s na configuração de megabloco (1.053 M de gás de bloco).
Possível mitigação: recuperação de remetente acelerada por GPU.
2. Modelo de precificação de gás
O point_evaluation a pré-compilação e a recuperação do remetente para transações 7702 apresentam baixa eficiência de gás por tempo. Os preços do gás poderão ter de ser revistos na era EIP-7928.
3. Limite de gás de transação
Limites mais altos de gás de bloco podem exigir a manutenção do atual limite de gás de transação para manter alto paralelismo.
4. Acelerando a construção do BAL
Espera-se que o desempenho do construtor se torne o gargalo dominante. Melhorar a construção do BAL é essencial para acompanhar o rendimento da execução pura.
5. Otimizando o Compromisso de Estado
O compromisso estatal é outro grande gargalo. Acelerar a computação da raiz do estado e otimizar o try commit são necessários para sustentar a execução de alto rendimento.
Também exploramos diferentes estratégias de agendamento de tarefas, por exemplo, priorizando transações de gás pesado, classificando-as por gás usado ou limite de gás, juntamente com o agendador de lista ordenada simples (OLS), onde as transações permanecem em ordem de bloco natural e cada nova transação é atribuída ao primeiro núcleo disponível. No entanto, quando aplicado aos dados da rede principal, a priorização das transações de gás pesado produziu apenas melhorias marginais de desempenho e não afetou significativamente o rendimento geral.
Taxa de transferência sob diferentes estratégias de agendamento
Para avaliar o impacto no rendimento geral, comparamos primeiro o agendamento de transações de gás pesado (por gás utilizado ou limite de gás) com o OLS.
- resultados em blocos normais:
| Tópicos (Agendador) | Taxa de transferência (MGas/s) | Maior latência de Txs | Tempo total |
|---|---|---|---|
| 2 (gás usado) | 2.726 | 5,70s | 15,45s |
| 2 (limite de gás) | 2.728 | 5,68s | 15,44s |
| 2 (OLS) | 2.460 | 6,04s | 17,12s |
| 4 (gás usado) | 4.401 | 6,09s | 9,57s |
| 4 (limite de gás) | 4.321 | 6,18s | 9,75s |
| 4 (OLS) | 3.753 | 6,10s | 10,71s |
| 8 (gás usado) | 5.455 | 6,15s | 7,72s |
| 8 (limite de gás) | 5.426 | 6,13s | 7,76s |
| 8 (OLS) | 4.824 | 6h00 | 8,73s |
| 16 (gás usado) | 5.643 | 6,03s | 7,47s |
| 16 (limite de gás) | 5.531 | 6,05s | 7,62s |
| 16 (OLS) | 5.084 | 6,04s | 8,28s |
- resultados em megablocos com gás de bloco médio de 1.053 milhões:
| Tópicos (Agendador) | Taxa de transferência (MGas/s) | Maior latência de Txs | Tempo total |
|---|---|---|---|
| 2 (limite de gás) | 2.732 | 0,53s | 15,42s |
| 2 (OLS) | 2.793 | 0,50s | 15.08s |
| 4 (limite de gás) | 5.114 | 0,54s | 8,24s |
| 4 (OLS) | 5.167 | 0,52s | 8h15s |
| 8 (limite de gás) | 9.082 | 0,57s | 4,64s |
| 8 (OLS) | 9.095 | 0,54s | 4,63s |
| 16 (limite de gás) | 14.181 | 0,63s | 2,97s |
| 16 (OLS) | 14.001 | 0,59s | 3,01s |
A análise de Toni sugere que a priorização das transações de gás pesado poderia superar o OLS em 20-80% nos piores cenários. Na prática, porém, usando dados reais da rede principal (representando o caso médio), a melhoria é de apenas cerca de 10%, e o agendamento por limite de gás, gás utilizado ou OLS mostra uma diferença mínima. Em megablocos, o OLS tem desempenho quase idêntico ao agendamento de limite de gás. Estas observações indicam que o agendamento de transações não é o principal gargalo; em vez disso, a distribuição inerente das transações na rede principal constitui o caminho crítico.
Fontesethresear



