Skip to content

Commit 915b603

Browse files
authored
chore(avm)!: gas gt migrations optimized (#16989)
This PR re-introduces the reverted PR #16856 which caused a performance regression in "Log derivative inverse commitments". After the introduction of separate destination lookup selectors, this original PR does not affect the performance. We introduce a specific gt selectors for the gas accounting (gt.sel_gas) while for the specific gt lookups involved by the CALL opcode, we used the already existing gt.sel_others selector. The reason is that we expect much less gt events produced by the latter one. Benchmarks on mainframe with 16 cores did not lead to any significant performance changes (ca. 2.5 seconds for the derivative inverse commitments).
1 parent 5217989 commit 915b603

30 files changed

+405
-489
lines changed

barretenberg/cpp/pil/vm2/context.pil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,8 @@ namespace execution;
485485

486486
// If any error happened during execution (i.e., sel_error=1), all gas should be consumed.
487487
pol SEL_CONSUMED_ALL_GAS = sel_error;
488-
(l2_gas_limit - PREV_GAS_PLUS_USAGE_L2) * SEL_CONSUMED_ALL_GAS + PREV_GAS_PLUS_USAGE_L2 - l2_gas_used = 0;
489-
(da_gas_limit - PREV_GAS_PLUS_USAGE_DA) * SEL_CONSUMED_ALL_GAS + PREV_GAS_PLUS_USAGE_DA - da_gas_used = 0;
488+
(l2_gas_limit - total_gas_l2) * SEL_CONSUMED_ALL_GAS + total_gas_l2 - l2_gas_used = 0;
489+
(da_gas_limit - total_gas_da) * SEL_CONSUMED_ALL_GAS + total_gas_da - da_gas_used = 0;
490490

491491
// nested_exit_call = 1 <==> prev_gas_used' = parent_gas_used + gas_used
492492
// sel_enter_call = 1 <==> prev_gas_used' = 0

barretenberg/cpp/pil/vm2/execution/gas.pil

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
include "../precomputed.pil";
2-
include "../range_check.pil";
2+
include "../gt.pil";
33

44
// This is a virtual gadget, which is part of the execution trace.
55
// https://excalidraw.com/#json=-fkwtFjYVOq2Z69Q351AE,O3SbjwK5eHX7-Oz2OH8RqQ
@@ -49,8 +49,8 @@ namespace execution;
4949
// ==== COMPARISON AGAINST THE LIMITS ====
5050

5151
// We will sum up all the gas used (base and dynamic) and compare just once.
52-
pol TOTAL_L2_GAS_USED = BASE_L2_GAS + DYNAMIC_L2_GAS_USED;
53-
pol TOTAL_DA_GAS_USED = base_da_gas + DYNAMIC_DA_GAS_USED;
52+
pol L2_GAS_USED = BASE_L2_GAS + DYNAMIC_L2_GAS_USED;
53+
pol DA_GAS_USED = base_da_gas + DYNAMIC_DA_GAS_USED;
5454

5555
// We are going to do 64 bit comparisons. If we assume:
5656
// prev_l2_gas_used to be u32::MAX_VALUE
@@ -59,43 +59,24 @@ namespace execution;
5959
// dynamic_da_gas to be u32::MAX_VALUE
6060
// Then prev_l2_gas_used + BASE_L2_GAS + dynamic_l2_gas_factor*dynamic_da_gas is exactly u64::MAX_VALUE.
6161

62-
pol commit constant_64;
63-
sel_should_check_gas * (64 - constant_64) = 0;
64-
65-
pol commit out_of_gas_l2;
66-
out_of_gas_l2 * (1 - out_of_gas_l2) = 0;
67-
pol commit out_of_gas_da;
68-
out_of_gas_da * (1 - out_of_gas_da) = 0;
69-
70-
pol PREV_GAS_PLUS_USAGE_L2 = prev_l2_gas_used + TOTAL_L2_GAS_USED;
71-
// Assumes l2_gas_limit is 32 bit and PREV_GAS_PLUS_USAGE_L2 is 64 bit
72-
// So we perform a 64 bit comparison
73-
pol LIMIT_GTE_USED_L2 = l2_gas_limit - PREV_GAS_PLUS_USAGE_L2;
74-
pol LIMIT_LT_USED_L2 = PREV_GAS_PLUS_USAGE_L2 - l2_gas_limit - 1;
75-
pol commit limit_used_l2_cmp_diff;
76-
// We multiply by sel_should_check_gas to force a 0 if we shouldn't check the gas.
77-
#[L2_CMP_DIFF]
78-
limit_used_l2_cmp_diff = sel_should_check_gas * ((LIMIT_LT_USED_L2 - LIMIT_GTE_USED_L2) * out_of_gas_l2 + LIMIT_GTE_USED_L2);
79-
80-
#[LIMIT_USED_L2_RANGE]
81-
sel_should_check_gas { limit_used_l2_cmp_diff, constant_64 }
82-
in
83-
range_check.sel { range_check.value, range_check.rng_chk_bits };
84-
85-
pol PREV_GAS_PLUS_USAGE_DA = prev_da_gas_used + TOTAL_DA_GAS_USED;
86-
// Assumes da_gas_limit is 32 bit and PREV_GAS_PLUS_USAGE_DA is 64 bit
87-
// So we perform a 64 bit comparison
88-
pol LIMIT_GTE_USED_DA = da_gas_limit - PREV_GAS_PLUS_USAGE_DA;
89-
pol LIMIT_LT_USED_DA = PREV_GAS_PLUS_USAGE_DA - da_gas_limit - 1;
90-
pol commit limit_used_da_cmp_diff;
91-
// We multiply by sel_should_check_gas to force a 0 if we shouldn't check the gas.
92-
#[DA_CMP_DIFF]
93-
limit_used_da_cmp_diff = sel_should_check_gas * ((LIMIT_LT_USED_DA - LIMIT_GTE_USED_DA) * out_of_gas_da + LIMIT_GTE_USED_DA);
94-
95-
#[LIMIT_USED_DA_RANGE]
96-
sel_should_check_gas { limit_used_da_cmp_diff, constant_64 }
97-
in
98-
range_check.sel { range_check.value, range_check.rng_chk_bits };
62+
pol commit out_of_gas_l2; // Boolean constraint enforced through lookup into gt.
63+
pol commit out_of_gas_da; // Boolean constraint enforced through lookup into gt.
64+
65+
// TODO: Once we support expression in lookup, we can replace this column by an alias.
66+
pol commit total_gas_l2;
67+
total_gas_l2 = prev_l2_gas_used + L2_GAS_USED;
68+
// Assumes l2_gas_limit is 32 bit and total_gas_l2 is 64 bit.
69+
70+
#[IS_OUT_OF_GAS_L2]
71+
sel_should_check_gas { total_gas_l2, l2_gas_limit, out_of_gas_l2 } in gt.sel_gas { gt.input_a, gt.input_b, gt.res };
72+
73+
// TODO: Once we support expression in lookup, we can replace this column by an alias.
74+
pol commit total_gas_da;
75+
total_gas_da = prev_da_gas_used + DA_GAS_USED;
76+
// Assumes da_gas_limit is 32 bit and total_gas_da is 64 bit.
77+
78+
#[IS_OUT_OF_GAS_DA]
79+
sel_should_check_gas { total_gas_da, da_gas_limit, out_of_gas_da } in gt.sel_gas { gt.input_a, gt.input_b, gt.res };
9980

10081
pol commit sel_out_of_gas;
10182
sel_out_of_gas = 1 - (1 - out_of_gas_l2) * (1 - out_of_gas_da);

barretenberg/cpp/pil/vm2/ff_gt.pil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace ff_gt;
4646
pol commit a;
4747
pol commit b;
4848
pol commit result;
49-
(result * (1 - result)) = 0;
49+
result * (1 - result) = 0;
5050

5151
// Should be looked up based on this selector
5252
// This will be off when doing the shifts for the remaning range constraints.

barretenberg/cpp/pil/vm2/gt.pil

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@ namespace gt;
2121
pol commit sel_sha256;
2222
pol commit sel_addressing;
2323
pol commit sel_alu;
24+
pol commit sel_gas;
2425
pol commit sel_others; // Any other lookup into this trace.
2526
sel_sha256 * (1 - sel_sha256) = 0;
2627
sel_addressing * (1 - sel_addressing) = 0;
2728
sel_alu * (1 - sel_alu) = 0;
29+
sel_gas * (1 - sel_gas) = 0;
2830
sel_others * (1 - sel_others) = 0;
2931
// If any of the above selectors is 1, then sel must be 1.
30-
(sel_sha256 + sel_addressing + sel_alu + sel_others) * (1 - sel) = 0;
32+
(sel_sha256 + sel_addressing + sel_alu + sel_gas + sel_others) * (1 - sel) = 0;
3133

3234
#[skippable_if]
3335
sel = 0;

barretenberg/cpp/pil/vm2/opcodes/external_call.pil

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,39 @@ namespace execution;
88
#[skippable_if]
99
sel_enter_call = 0;
1010

11-
// TODO: Remove this as a column when we can lookup with constants
12-
pol commit constant_32;
13-
sel_enter_call * (32 - constant_32) = 0;
14-
1511
// ==== GAS CLAMPING ====
1612
// Guaranteed not to wrap since we never put a gas used > gas limit
17-
pol L2_GAS_LEFT = l2_gas_limit - l2_gas_used;
18-
pol DA_GAS_LEFT = da_gas_limit - da_gas_used;
13+
14+
// TODO: Once we support expression in lookup, we can replace this column by an alias.
15+
pol commit l2_gas_left;
16+
l2_gas_left = sel_enter_call * (l2_gas_limit - l2_gas_used);
17+
18+
// TODO: Once we support expression in lookup, we can replace this column by an alias.
19+
pol commit da_gas_left;
20+
da_gas_left = sel_enter_call * (da_gas_limit - da_gas_used);
21+
1922

2023
// L2 gas clamping
2124

2225
// Compare the gas allocated to the call by the user, with the gas left.
2326
// Helper column containing whether the allocated gas is less than the left gas
24-
pol commit call_is_l2_gas_allocated_lt_left;
25-
call_is_l2_gas_allocated_lt_left * (1 - call_is_l2_gas_allocated_lt_left) = 0;
27+
pol commit call_is_l2_gas_allocated_lt_left; // Guaranteed to be boolean through the gt lookup. (provided that sel_enter_call == 1)
2628

29+
#[CALL_IS_L2_GAS_ALLOCATED_LT_LEFT]
30+
sel_enter_call { l2_gas_left, register[0], call_is_l2_gas_allocated_lt_left } in gt.sel_others { gt.input_a, gt.input_b, gt.res };
2731

28-
pol ALLOCATED_GTE_LEFT_L2 = register[0] - L2_GAS_LEFT;
29-
pol ALLOCATED_LT_LEFT_L2 = L2_GAS_LEFT - register[0] - 1;
30-
pol commit call_allocated_left_l2_cmp_diff;
31-
sel_enter_call * ((ALLOCATED_LT_LEFT_L2 - ALLOCATED_GTE_LEFT_L2) * call_is_l2_gas_allocated_lt_left + ALLOCATED_GTE_LEFT_L2 - call_allocated_left_l2_cmp_diff) = 0;
32+
// next row's l2_gas_limit = if call_is_l2_gas_allocated_lt_left { register[0] } else { l2_gas_left }
33+
sel_enter_call * ((register[0] - l2_gas_left) * call_is_l2_gas_allocated_lt_left + l2_gas_left - l2_gas_limit') = 0;
3234

33-
#[CALL_ALLOCATED_LEFT_L2_RANGE]
34-
sel_enter_call { call_allocated_left_l2_cmp_diff, constant_32 }
35-
in
36-
range_check.sel
37-
{ range_check.value, range_check.rng_chk_bits };
38-
39-
// next row's l2_gas_limit = if call_is_l2_gas_allocated_lt_left { register[0] } else { L2_GAS_LEFT }
40-
sel_enter_call * ((register[0] - L2_GAS_LEFT) * call_is_l2_gas_allocated_lt_left + L2_GAS_LEFT - l2_gas_limit') = 0;
4135

4236
// DA gas clamping
4337

4438
// Compare the gas allocated to the call by the user, with the gas left.
4539
// Helper column containing whether the allocated gas is less than the left gas
46-
pol commit call_is_da_gas_allocated_lt_left;
47-
call_is_da_gas_allocated_lt_left * (1 - call_is_da_gas_allocated_lt_left) = 0;
48-
49-
pol ALLOCATED_GTE_LEFT_DA = register[1] - DA_GAS_LEFT;
50-
pol ALLOCATED_LT_LEFT_DA = DA_GAS_LEFT - register[1] - 1;
51-
pol commit call_allocated_left_da_cmp_diff;
52-
sel_enter_call * ((ALLOCATED_LT_LEFT_DA - ALLOCATED_GTE_LEFT_DA) * call_is_da_gas_allocated_lt_left + ALLOCATED_GTE_LEFT_DA - call_allocated_left_da_cmp_diff) = 0;
53-
54-
#[CALL_ALLOCATED_LEFT_DA_RANGE]
55-
sel_enter_call { call_allocated_left_da_cmp_diff, constant_32 }
56-
in
57-
range_check.sel
58-
{ range_check.value, range_check.rng_chk_bits };
40+
pol commit call_is_da_gas_allocated_lt_left; // Guaranteed to be boolean through the gt lookup. (provided that sel_enter_call == 1)
5941

60-
// next row's da_gas_limit = if call_is_da_gas_allocated_lt_left { reg2 } else { DA_GAS_LEFT }
61-
sel_enter_call * ((register[1] - DA_GAS_LEFT) * call_is_da_gas_allocated_lt_left + DA_GAS_LEFT - da_gas_limit') = 0;
42+
#[CALL_IS_DA_GAS_ALLOCATED_LT_LEFT]
43+
sel_enter_call { da_gas_left, register[1], call_is_da_gas_allocated_lt_left } in gt.sel_others { gt.input_a, gt.input_b, gt.res };
6244

45+
// next row's da_gas_limit = if call_is_da_gas_allocated_lt_left { register[1] } else { da_gas_left }
46+
sel_enter_call * ((register[1] - da_gas_left) * call_is_da_gas_allocated_lt_left + da_gas_left - da_gas_limit') = 0;

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/addressing.test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#include <cstdint>
55

6-
#include "barretenberg/common/serialize.hpp"
76
#include "barretenberg/vm2/common/memory_types.hpp"
87
#include "barretenberg/vm2/constraining/flavor_settings.hpp"
98
#include "barretenberg/vm2/constraining/testing/check_relation.hpp"

0 commit comments

Comments
 (0)