# 性能

> v1.0.0 的每一项实测数据及其来源：一个完整以太坊区块的基础证明、递归树、判定器与合约、每个电路族的分片证明，以及 Mercury 本身的成本。

所有端到端数据都来自 `glamsterdam-devnet-8` 的第 257,510 号区块，经由无状态校验器客户程序（guest）证明：60 笔交易，101.5 Mgas，1.98 亿个周期。每一项数据都来自规范中的测量。

## 端到端

| 阶段 | 机器 | 结果 |
| --- | --- | --- |
| 基础证明 | 32 vCPU，247.7 GiB，同时处理 12 个分片 | 207 个分片，14.5 MB，2,481 s；峰值 173.92 GiB |
| 递归叶节点 | 32 CPU，四个叶节点同时进行 | 21、24、23 和 27 个分片；2,157 s；峰值 92 GiB |
| 递归根节点 | 同一台机器，同时处理四个分片 | 21 个分片，460 s，1.03 MB |
| 判定器仪式 | 18 核笔记本电脑 | `init` 65 s；每份贡献 50–56 s；`key` 70 s、12.7 GB；密钥 2.65 GB |
| 判定器证明 | 18 核笔记本电脑 | 读取密钥 1 s，证明 18.5 s，6.1 GB；7,896,686 个约束，定义域大小为 `2^23` |
| 链上验证 | revm | 3,620,026 gas；34,980 字节 calldata；358 个点 |

## 基础证明，逐遍拆解

| | |
| --- | --- |
| 第一遍，承诺 | 191 s；平均 25.7 个 vCPU 处于忙碌；单线程填充占其分片秒数的 81%；采样内存至多 15.9 GiB |
| 第二遍，证明 | 2,290 s；客户程序退出之前，12 个分片名额中平均有 11.95 个被占用，30.4 个 vCPU 处于忙碌；随后是 460 s 的尾段，其中最长的两段是两个 `KECCAK_F` 分片的单线程填充，分别为 200 s 和 279 s |
| 内存峰值 | 173.92 GiB：两个 `2^18` 的 `KECCAK_F` 分片，在尾段同时处理，此外再无其他分片在处理中 |

峰值由某一个委托电路族的高度决定，而不是由同时处理中的分片数决定。

## 一个小型客户程序

快速上手中的客户程序，在四个指令电路族中运行 114 个周期，以 `2^20` 的指令高度和 `2^16` 的窗口高度、同时处理两个分片进行证明：在一台 18 核、48 GiB 内存的笔记本电脑上，共 7 个分片，耗时 52 s，峰值 18 GB，几乎全部来自正在处理的两个 `2^20` 分片。证明的下限由其电路族和高度决定，而不是由周期数决定。

## 每个电路族的分片

以下均为默认高度下的数据。分片证明的大小由其电路的形状和高度确定；证明成本取决于高度与电路宽度的乘积，不论有多少行是有效行。

| 电路族 | 高度 | 已承诺 `M`/`W`/`S` | 约束门 | 内部列 | 分片证明 |
| --- | --- | --- | --- | --- | --- |
| `ADD_SUB_LUI_AUIPC` | `2^22` | 27 / 35 / 7 | 63 | 314 | 64,764 B |
| `JUMP_BRANCH_SLT` | `2^22` | 21 / 44 / 10 | 42 | 392 | 69,436 B |
| `SHIFT_BITWISE` | `2^22` | 21 / 61 / 10 | 48 | 478 | 76,644 B |
| `MUL_DIV` | `2^20` | 21 / 54 / 9 | 54 | 444 | 67,412 B |
| `MEM_WORD` | `2^22` | 31 / 24 / 7 | 33 | 314 | 63,836 B |
| `MEM_SUBWORD` | `2^22` | 31 / 55 / 10 | 53 | 472 | 76,196 B |
| `ATOMICS` | `2^20` | 26 / 54 / 9 | 46 | 472 | 68,468 B |
| `INIT_TEARDOWN` | `2^22` | 2 / 0 / 1 | 0 | 46 | 36,316 B |
| `ZERO_WINDOWS` | `2^22` | 2 / 0 / 0 | 0 | 46 | 36,284 B |
| `KECCAK_F` | `2^18` | 208 / 1,556 / 0 | 385 | 5,490 | 381,100 B |
| `POSEIDON2` | `2^8` | 100 / 4,092 / 0 | 4,248 | 2,020 | 664,780 B |
| `FR_ARITH` | `2^8` | 104 / 2,576 / 0 | 2,701 | 142 | 266,292 B |
| `PUBLIC_INPUT`、`PUBLIC_OUTPUT` | `2^12` | 3 或 2 / 0 / 0 | 0 | 26 | 12,556 B、12,524 B |
| `ADVICE_WINDOWS` | `2^22` | 3 / 0 / 0 | 0 | 46 | 36,316 B |
| `MOD_MUL` | `2^16` | 104 / 221 / 0 | 125 | 2,244 | 135,220 B |
| `SHA256_COMP` | `2^18` | 104 / 520 / 0 | 119 | 2,802 | 189,988 B |
| `EC_ADD` | `2^16` | 392 / 1,028 / 0 | 637 | 8,772 | 434,916 B |

高度只改变折半列表的数量和求和校验（sumcheck）的轮数，不改变门：`ADD_SUB_LUI_AUIPC` 在 `2^20` 时有 298 个内部列，证明为 57,196 字节，而在 `2^22` 时分别为 314 个和 64,764 字节。

## 前向过程的内存

GKR 证明者以域元素的形式持有每个内部层，每个单元 32 字节。代表性的工作集：

| 分片 | 前向过程 |
| --- | --- |
| `2^20` 的 `SHIFT_BITWISE` | 8.4 GiB |
| `2^16` 的 `MOD_MUL` | 4.6 GB |
| `2^16` 的 `EC_ADD` | 18.3 GB |
| `2^18` 的 `SHA256_COMP` | 22.6 GB |
| `2^18` 的 `KECCAK_F` | 42 GiB |

## Mercury

在一台 18 核的 Apple M5 Pro 上：

| | |
| --- | --- |
| 承诺，`n = 2^22` | 1.30 s |
| 打开，`n = 2^22` | 2.89 s |
| 16 个 `2^20` 的列作为一批 | 打开耗时 1.01 s，验证耗时 4.8 ms |
| 同样 16 列逐个打开 | 9.79 s，验证耗时 62 ms |

## 如何解读这些数字

证明受内存限制，其内存取决于同时处理中的分片及其高度，从不取决于执行的长度。时间取决于各电路族各自的周期数。链上成本取决于根节点欠最终配对的点数，每个点约 9,000 gas。周期数本身是精确的，且与机器无关，所以要估算其余任何一项，周期分析器都是首选工具。
