
Bài viết của Lin Oshitani ( Nethermind Research ). Xin cảm ơn Matteo , Ahmad , Michal , Conor , Gustavo , Daniel , David , Yuewang và Ignacio vì những cuộc thảo luận và/hoặc đánh giá, và cảm ơn Musa vì những cuộc thảo luận và đã giúp chạy các bài kiểm tra hiệu năng.
Công trình này được tài trợ bởi Taiko như một phần của quan hệ đối tác chiến lược Taiko<>Nethermind .
Tóm lại
Chi phí chứng minh riêng lẻ của mỗi opcode là bao nhiêu? Để trả lời câu hỏi này, chúng tôi đo hiệu năng thời gian chứng minh trên mỗi gas của từng opcode và precompiled Máy ảo Ethereum (EVM) trong thiết lập đa GPU, dựa trên công cụ đo hiệu năng zkEVM của EF và phương pháp ước tính chi phí gas của nhóm imapp. Chúng tôi cũng đánh giá xem chu kỳ zk có phải là một chỉ số gần đúng có ý nghĩa cho thời gian chứng minh thực tế hay không bằng cách sử dụng các phép đo thời gian chứng minh thực tế.
Giới thiệu
Khi các quy trình ZK tiến tới phi tập trung hóa hơn nữa, cả về các giai đoạn cuộn và sự phi tập trung hóa của các bộ điều khiển trình tự và bộ chứng minh, việc giảm thiểu các khối gây hại cho bộ chứng minh trở nên cực kỳ quan trọng đối với tính bảo mật và tính bền vững kinh tế của chúng. Các khối đối kháng này được tạo ra để tối đa hóa thời gian chứng minh trong khi vẫn nằm trong Gas Limit Máy ảo Ethereum (EVM) , tạo ra các vectơ tấn công từ chối dịch vụ tiềm tàng hoặc khiến việc chứng minh trở nên không khả thi về mặt kinh tế. Hơn nữa, khi chính Ethereum L1 tiến tới mở rộng quy mô dựa trên ZK , nó cũng sẽ phải đối mặt với thách thức tương tự.
Phương pháp đo lường gas Máy ảo Ethereum (EVM) truyền thống chỉ tính đến chi phí thực thi như thời gian CPU, truy cập bộ nhớ và tăng trưởng trạng thái, nhưng không thể bao quát toàn bộ chi phí chứng minh. Do đó, việc tổng hợp ZK yêu cầu các biện pháp bảo vệ bổ sung. Một phương pháp hàng đầu là đo lường rõ ràng chi phí chứng minh và áp đặt giới hạn Block dựa trên chỉ số này. Tuy nhiên, việc xây dựng các cơ chế như vậy đòi hỏi các mô hình chính xác về cách các thao tác riêng lẻ đóng góp vào tổng thời gian chứng minh, đủ chính xác để ngăn chặn các khối tấn công mà không làm ảnh hưởng quá nhiều đến khả năng sử dụng.
Để mô hình hóa thời gian chứng minh, chúng tôi tập trung vào câu hỏi cốt lõi sau: mỗi mã lệnh Máy ảo Ethereum (EVM) hoặc lệnh biên dịch trước đóng góp như thế nào vào tổng thời gian chứng minh? Cụ thể, nếu chúng ta thêm một mã lệnh hoặc lệnh biên dịch trước tiêu tốn thêm X gas, giữ nguyên các yếu tố khác, thì nó sẽ thêm bao nhiêu thời gian chứng minh? Từ đó, chúng tôi ước tính thời gian chứng minh biên trên mỗi đơn vị gas cho mỗi mã lệnh hoặc lệnh biên dịch trước.
Các nỗ lực đánh giá hiệu năng zkEVM trước đây của Ethereum Foundation cung cấp các phép đo đầu cuối có giá trị bằng cách xây dựng các khối chứa đầy một mã lệnh hoặc mã biên dịch trước cụ thể thông qua một vòng lặp. Cách tiếp cận này hoạt động tốt để xác định và phân tích các thao tác có chi phí chứng minh rất cao, trong đó chi phí của thao tác mục tiêu chiếm ưu thế trong tổng thời gian chứng minh. Tuy nhiên, vì các phép đo hiệu năng này không tách biệt rõ ràng chi phí cho mỗi thao tác khỏi chi phí phụ xung quanh (ví dụ: đẩy đối số vào ngăn xếp, lấy giá trị trả về và luồng điều khiển), chúng ít cung cấp thông tin hơn đối với các thao tác có chi phí thấp hơn, nơi mã xung quanh có thể ảnh hưởng đáng kể đến phép đo. Do đó, chúng không đủ để xây dựng một mô hình toàn diện về thời gian chứng minh trên tất cả các mã lệnh và mã biên dịch trước.
Để khắc phục hạn chế này, chúng tôi áp dụng phương pháp đo lường cận biên từ dự án Gas Cost Estimator của nhóm imapp, phương pháp này tách biệt đóng góp của từng mã lệnh hoặc quá trình biên dịch trước khỏi chi phí chung xung quanh bằng cách tạo ra các trường hợp thử nghiệm chỉ thay đổi số lượng thao tác mục tiêu trong khi giữ nguyên tất cả các ngữ cảnh thực thi khác. Sau đó, chúng tôi sử dụng hồi quy tuyến tính và lấy độ dốc để ước tính thời gian chứng minh trên mỗi đơn vị gas.
Việc triển khai chuẩn của chúng tôi được xây dựng dựa trên và thực hiện được nhờ nền tảng của công cụ đo chuẩn zkEVM của Ethereum Foundation. Chúng tôi đã tạo ra một bộ kiểm thử đặc tả thực thi tùy chỉnh theo phương pháp cận biên của công cụ ước tính chi phí gas, với các phần mở rộng để phù hợp hơn với bối cảnh chứng minh ZK (ví dụ: một phương pháp khuếch đại để ngăn chặn chi phí thiết lập chứng minh ZK cố định chi phối các phép đo). Sau đó, các bài kiểm thử này được thực thi bằng cách sử dụng một Fork tùy chỉnh của công cụ đo chuẩn của EF với hỗ trợ đa GPU được thêm vào cho SP1.
Hơn nữa, chúng tôi sử dụng kết quả đánh giá hiệu năng để xem liệu chu kỳ zk có phải là một chỉ số thay thế hợp lý cho thời gian chứng minh thực tế bằng cách sử dụng các phép đo thời gian chứng minh trực tiếp hay không. Chúng tôi nhận thấy rằng mối quan hệ giữa thời gian chứng minh và chu kỳ zk thay đổi rất nhiều giữa các mã lệnh và mã biên dịch trước, làm hạn chế độ chính xác của các ước tính dựa trên chu kỳ zk.
Kết quả chính
Chúng tôi trình bày kết quả trước; độc giả quan tâm đến các giả định và thiết lập thí nghiệm có thể tìm thấy thông tin chi tiết trong phần Phương pháp luận .
Trong phần này, chúng tôi trình bày các kết quả chính của các bài kiểm tra hiệu năng, được thực hiện trong môi trường sau (để biết thêm chi tiết về thiết lập, xem phần phương pháp luận bên dưới):
Prover : sp1-v5.2.3 (với sp1-cluster) và risc0-v3.0.4 (với cờ
RISC0_KECCAK_PO2=15để ngăn các trình chứng minh bị lỗi)Card đồ họa : 4 x NVIDIA GeForce RTX 4090
Ứng dụng thực thi: reth-v1.9.3
Lưu ý: Thời gian chứng minh phụ thuộc rất nhiều vào cấu hình chạy (ví dụ: cờ và cấu hình của trình chứng minh, cài đặt phần cứng/thời gian chạy, tình trạng của GPU tại thời điểm chứng minh, ETC). Do đó, các kết quả này nên được hiểu là các phép đo cụ thể theo cấu hình.
Lưu ý: Các bài kiểm tra hiệu năng này được thực hiện mà không có xác thực Block Header . Thử nghiệm cục bộ cho thấy việc xác thực có ít tác dụng đối với hầu hết các mã lệnh; các mã lệnh liên quan đến LOG cho thấy mức tăng gấp 4-5 lần, mặc dù việc chứng minh chúng vẫn tương đối dễ dàng.
Thời gian thử nghiệm cho mỗi gas
Dưới đây là “thời gian chứng minh trên mỗi đơn gas” cho từng mã lệnh/biên dịch trước trong cả SP1 và RISC0. Chỉ số này thể hiện thời gian chứng minh bổ sung phát sinh do sử dụng thêm 1 đơn vị gas cho một mã lệnh hoặc biên dịch trước cụ thể. Giá trị R^2 cho biết độ phù hợp của hồi quy tuyến tính.
Dữ liệu chi tiết hơn (ví dụ: biểu đồ hồi quy cho từng mã lệnh) được lưu trữ tại đây: SP1 , RISC0
Một số quan sát sơ bộ:
Các công cụ biên dịch trước mật mã (ví dụ:
modexp,point_evaluation) nói chung có thời gian chứng minh trên mỗi gas rất cao.Các mã lệnh liên quan đến phép chia/phép lấy dư (
mulmod,mod,div,sdiv) có thời gian chứng minh tương đối cao, cũng nhưselfbalance.Các mã lệnh xung quanh log/create (
log1,log2,log3,create,create2) có thời gian chứng minh trên mỗi gas nhanh nhất đối với cả SP1 và RISC0, có thể là do chi phí gas của chúng chủ yếu dành cho dữ liệu và lưu trữ chứ không phải tính toán.Nhìn chung, thứ hạng tương đối của các opcode theo thời gian chứng minh là tương tự nhau giữa RISC0 và SP1, nhưng có một số ngoại lệ đáng chú ý (ví dụ:
keccak256chậm hơn khoảng 12 lần trên RISC0,sha256nhanh hơn khoảng 10 lần trên RISC0). Điều này có thể là do các bản biên dịch trước zkvm của một số opcode/bản biên dịch trước tồn tại trong hệ thống này nhưng không có trong hệ thống kia (để so sánh thêm giữa các trình chứng minh, xem biểu đồ trong Phụ lục: So sánh SP1/RISC0 ).
Thời gian chứng minh trên mỗi chu kỳ ZK
ZKVM có khái niệm về chu kỳ ZK , đại diện cho số bước tính toán mà ZKVM thực hiện để chứng minh một chương trình, tương tự như chu kỳ CPU trong điện toán truyền thống. Một câu hỏi đặt ra là: chu kỳ ZK có phải là thước đo chính xác cho thời gian chứng minh thực tế hay không? Nếu chu kỳ ZK tương quan tuyến tính với thời gian chứng minh trên tất cả các hoạt động, chúng có thể được sử dụng như một thước đo đơn giản hơn cho việc đo lường gas ZK. Tuy nhiên, nếu mối quan hệ không tuyến tính hoặc thay đổi đáng kể giữa các loại hoạt động, thì thời gian chứng minh phải được đo trực tiếp để bảo vệ DoS chính xác.
Để trả lời câu hỏi này, chúng tôi đã sử dụng phương pháp hồi quy tuyến tính để so sánh thời gian chứng minh với chu kỳ zk cho mỗi mã lệnh/biên dịch trước. Dưới đây là các kết quả.
Trong cùng một quy trình, mối quan hệ này rất tuyến tính (hệ số tương quan R^2 cao): tăng gấp đôi số chu kỳ sẽ tăng gấp đôi thời gian chứng minh. Tuy nhiên, tỷ lệ chuyển đổi từ chu kỳ sang thời gian không phải là phổ quát—nó phụ thuộc rất nhiều vào quy trình.
Biểu đồ cột bên dưới thể hiện "thời gian trên mỗi chu kỳ zk" cho mỗi thao tác. Nếu chu kỳ là một chỉ số tốt, tất cả các cột sẽ gần như trùng khớp; thay vào đó, chúng phân tán rộng rãi - có thể là do một số thao tác được thực hiện trong các mạch khác nhau (ví dụ: biên dịch trước zkVM tùy chỉnh). Ví dụ, trong SP1, bn128_add mất khoảng 930 ns trên mỗi chu kỳ zk trong khi pop chỉ mất khoảng 63 ns, chênh lệch khoảng 15 lần. Điều này cho thấy chỉ riêng chu kỳ zk là không đủ để đo lường chính xác thời gian chứng minh. Các biện pháp khắc phục bao gồm:
Máy đo sử dụng thời gian kiểm chứng đã được đo (như đã thực hiện trong bài đăng này)
Cải thiện việc tính toán chu kỳ để phản ánh chính xác hơn thời gian chứng minh (ví dụ: cải thiện việc chuyển đổi chu kỳ zk giữa các mạch khác nhau).
Hãy sử dụng chu kỳ ZK làm thước đo thời gian chứng minh, nhưng cần thận trọng, tức là sử dụng các số liệu từ thời gian chậm nhất cho mỗi thao tác trong chu kỳ ZK.
Phương pháp luận
Chúng tôi áp dụng phương pháp chi phí cận biên, ban đầu được nhóm imapp phát triển cho việc định giá lại gas L1 như một phần của dự án Gas Cost Estimator, để phân lập chi phí chứng minh của từng hoạt động riêng lẻ.
Đầu tiên, chúng tôi tạo ra 4-7 khối cho mỗi mã lệnh/lệnh biên dịch trước với số lượng thao tác khác nhau (0, N, 2N, 3N, ETC), đồng thời duy trì chi phí hoạt động không đổi bằng cách giữ cho tất cả các yếu tố khác giống hệt nhau giữa các biến thể—thiết lập ngăn xếp, khởi tạo bộ nhớ, luồng điều khiển và các thao tác dọn dẹp.
Bảng dưới đây là một ví dụ về cấu trúc mã bytecode cho lệnh ADD. Lưu ý rằng mỗi biến thể đều có chính xác 20 lệnh PUSH và 10 lệnh POP — Chỉ có số lượng lệnh ADD là khác nhau.
| op_count | Cài đặt | Chủ yếu | Dọn dẹp |
|---|---|---|---|
| 0 | ĐẨY×20 | — | POP×10 |
| 3 | ĐẨY×20 | ADD + (POP + ADD)×2 | POP×8 |
| 5 | ĐẨY×20 | ADD + (POP + ADD)×4 | POP×6 |
| 10 | ĐẨY×20 | ADD + (POP + ADD)×9 | POP×1 |
Tiếp theo, chúng ta thực thi từng biến thể Block và ghi lại tổng thời gian chứng minh và gas tiêu thụ của toàn bộ Block. Sau đó, chúng ta điều chỉnh proving_time = α × gas_used + β cho tất cả các biến thể. Dưới đây là một ví dụ cho mã lệnh ADD trong SP1:
Hệ số góc α biểu thị thời gian chứng minh biên trên mỗi đơn vị gas cho mã lệnh hoặc quá trình biên dịch trước đang được xem xét. Vì chỉ có số lượng thao tác mục tiêu thay đổi trong khi tất cả ngữ cảnh thực thi khác được giữ không đổi, α cô lập đóng góp của thao tác đó. Trong ví dụ trên, ta có α = 3.78µs , ngụ ý thời gian chứng minh trên mỗi gas là 3.78µs cho lệnh ADD trong SP1 với 4 GPU.
Đối số mã lệnh/biên dịch trước
Đối với các tham số mã lệnh/biên dịch trước, chúng tôi sử dụng các đầu vào cố định được chọn sao cho mang tính đại diện và, nếu có thể, là "trường hợp xấu nhất" trên cơ sở nỗ lực tối đa. Sự lựa chọn của chúng tôi được hướng dẫn bởi các mô hình trường hợp xấu nhất đã biết từ các bộ công cụ đánh giá hiệu năng hiện có . Việc sử dụng các đầu vào trường hợp xấu nhất giúp tránh vô tình đo lường các đường dẫn nhanh được tối ưu hóa chỉ xảy ra đối với các đầu vào đặc biệt (ví dụ: bộ đệm toàn số không).
Giả định làm việc của chúng tôi là thời gian chứng minh tỷ lệ thuận tuyến tính với mức tiêu thụ gas cho một thao tác nhất định, không chỉ trên các số lượng thao tác khác nhau mà còn trên các lựa chọn đối số khác nhau trong cùng một thao tác (tức là, nếu bạn tăng gấp đôi gas, bạn sẽ tăng gấp đôi thời gian chứng minh). Điều này giả định rằng (1) gas phản ánh chính xác độ phức tạp tính toán và (2) thời gian chứng minh tỷ lệ thuận với độ phức tạp đó.
Trên thực tế, giả định này có thể không chính xác, ví dụ, vì gas không phản ánh chính xác độ phức tạp tính toán hoặc vì ZKVM thể hiện hành vi khác nhau đối với một số đối số nhất định. Do đó, các phép đo của chúng tôi nên được hiểu là đặc thù cho các đầu vào đã được thử nghiệm và chỉ là các giá trị gần đúng cho các đầu vào khác. Một phân tích chi tiết hơn về chi phí chứng minh phụ thuộc vào đối số, xem xét thời gian chứng minh thay đổi như thế nào trên toàn bộ không gian đối số cho mỗi thao tác, sẽ được dành cho công việc trong tương lai.
Cuối cùng, đối với các thao tác như LOG và CREATE, nơi chi gas chủ yếu phụ thuộc vào kích thước dữ liệu và việc mở rộng bộ nhớ chứ không phải khả năng tính toán, chúng tôi sử dụng các đối số tiêu chuẩn (ví dụ: tải trọng 32 byte) chứ không phải các đối số trường hợp xấu nhất về mặt gas. Sử dụng tải trọng lớn sẽ làm tăng chi phí gas mà không làm tăng đáng kể khối lượng công việc chứng minh, dẫn đến việc đánh giá thấp chi phí chứng minh tính toán trên mỗi đơn vị gas .
Tích hợp với công cụ đánh giá hiệu năng EF
Quy trình đánh giá hiệu năng của chúng tôi được xây dựng dựa trên Khối lượng công việc đánh giá hiệu năng zkEVM của Ethereum Foundation, và chúng tôi giới thiệu hai phần mở rộng quan trọng:
Các bài kiểm tra/mô phỏng biên EEST tùy chỉnh : Chúng tôi thêm các bài kiểm tra đặc tả thực thi (EEST) tùy chỉnh tuân theo phương pháp luận biên.
Hỗ trợ SP1 đa GPU : Chúng tôi mở rộng công cụ đo hiệu năng ZKEVM của EF để hỗ trợ thực thi cụm SP1, cho phép chứng minh cùng một khối lượng công việc bằng cách sử dụng 4 GPU.
Với những bổ sung này, chúng tôi tạo ra các fixture EEST, chuyển đổi chúng thành đầu vào chứng thực zkEVM bằng công cụ EF, chạy quá trình chứng minh thông qua trình chạy máy chủ EF (SP1 trên 4 GPU hoặc RISC0), và sau đó xử lý hậu kỳ các số liệu thu được (thời gian chứng minh, gas, chu kỳ zk) để phù hợp với các phép hồi quy và trích xuất thời gian chứng minh biên trên mỗi gas (hoặc trên mỗi chu kỳ zk).
Hồ sơ đăng ký và các bước tiếp theo
Dưới đây là một số ứng dụng thực tiễn tiềm năng của các phép đo này:
Đo lường Block có nhận thức về ZK cho các khối tổng hợp ZK : Các phép đo thời gian chứng minh trên mỗi gas có thể được sử dụng để trực tiếp đo lường và giới hạn chi phí chứng minh của các khối. Cụ thể, người ta có thể định nghĩa một chỉ số "ZK Gas" bằng cách trọng số hóa lượng gas tiêu thụ bởi mỗi opcode/precompile với một hệ số nhân được suy ra từ thời gian chứng minh trên mỗi gas đã đo được. Bằng cách giới hạn tổng ZK Gas trên mỗi Block, giao thức có thể giới hạn thời gian chứng minh trong trường hợp xấu nhất và giảm thiểu các khối gây mất chứng minh.
Hướng dẫn dành cho người triển khai zkVM : Phân tích chi tiết từng thao tác giúp làm nổi bật các mã lệnh/lệnh biên dịch trước cần cải thiện, giúp các nhóm zkVM ưu tiên tối ưu hóa (ví dụ: các mạch chuyên dụng). Nó cũng cung cấp tín hiệu cụ thể để cải thiện việc tính toán chu kỳ ZK sao cho số chu kỳ ZK theo dõi thời gian chứng minh một cách đồng nhất hơn trên các đường dẫn mạch khác nhau.
Hướng dẫn dành cho các nhóm triển khai phía khách hàng : Các nhóm khách hàng có thể sử dụng các số liệu đo lường này để xác định các điểm nóng không thân thiện với ZK và tối ưu hóa các triển khai mã lệnh/biên dịch trước hoặc các mẫu thực thi cụ thể nhằm giảm chi phí chứng minh.
Các bước tiếp theo của dự án như sau:
Đánh giá hiệu suất dựa trên lập luận : Mở rộng phương pháp luận để bao quát tất cả các yếu tố đầu vào.
Giám sát hiệu năng liên tục : Tự động hóa toàn bộ quy trình (tạo fixture → tạo witness → kiểm chứng → kiểm thử hồi quy → báo cáo) để có thể theo dõi hiệu năng của từng opcode/precompile zkVM/client theo thời gian.
Đo lường đa chiều : Nghiên cứu cách tích hợp các phép đo này vào hệ thống đo lường gas đa chiều .
Liên kết
Dữ liệu chi tiết về các bài kiểm tra hiệu năng của chúng tôi (ví dụ: biểu đồ hồi quy cho từng mã lệnh/biên dịch trước):
Các bài kiểm tra execution-spec tùy chỉnh được sử dụng cho các bài kiểm tra hiệu năng: https://github.com/linoscope/execution-specs/pull/1/changes
Các yêu cầu kéo (PR) để hỗ trợ cụm SP1 trong công cụ EF:
Bài thuyết trình hay về công cụ đo hiệu năng ZK của EF do Ignacio trình bày: https://youtu.be/D2TpmD62tjQ?si=D4mzEagb2MXX1QXy&t=1510
Bài thuyết trình hay về phương pháp cận biên của Jacek: https://www.youtube.com/watch?v=KmaFpyV9jvM
Phụ lục: So sánh SP1/RISC0
Biểu đồ bên dưới thể hiện (RISC0 proving_time_per_gas) / (SP1 proving_time_per_gas) , trong đó proving_time_per_gas mỗi gas là độ dốc hồi quy cho mã lệnh của mỗi trình chứng minh. Đường tham chiếu ở mức 1,0× có nghĩa là hiệu suất bằng nhau. Giá trị > 1,0× cho thấy RISC0 chậm hơn (mất nhiều thời gian chứng minh trên mỗi gas hơn SP1 cho mã lệnh/biên dịch trước đó), và giá trị < 1,0× cho thấy SP1 chậm hơn.








