@@ -11,14 +11,8 @@ use openvm_instructions::{
11
11
use openvm_stark_backend:: prover:: { hal:: ProverBackend , types:: DeviceMultiStarkProvingKey } ;
12
12
13
13
use crate :: {
14
- arch:: {
15
- execution_mode:: tracegen:: TracegenCtx , Arena , DenseRecordArena , PreflightExecutor ,
16
- VmExecState ,
17
- } ,
18
- system:: {
19
- memory:: { adapter:: AccessAdapterInventory , online:: TracingMemory } ,
20
- program:: PcEntry ,
21
- } ,
14
+ arch:: { execution_mode:: tracegen:: TracegenCtx , Arena , PreflightExecutor , VmExecState } ,
15
+ system:: { memory:: online:: TracingMemory , program:: PcEntry } ,
22
16
} ;
23
17
24
18
pub mod cycle_tracker;
@@ -60,6 +54,7 @@ pub struct VmMetrics {
60
54
pub fn update_instruction_metrics < F , RA , Executor > (
61
55
state : & mut VmExecState < F , TracingMemory , TracegenCtx < RA > > ,
62
56
executor : & mut Executor ,
57
+ prev_pc : u32 , // the pc of the instruction executed, state.pc is next pc
63
58
pc_entry : & PcEntry < F > ,
64
59
) where
65
60
F : Clone + Send + Sync ,
@@ -80,59 +75,68 @@ pub fn update_instruction_metrics<F, RA, Executor>(
80
75
let opcode = pc_entry. insn . opcode ;
81
76
let opcode_name = executor. get_opcode_name ( opcode. as_usize ( ) ) ;
82
77
83
- let num_sys_airs = state. metrics . num_sys_airs ;
84
- let access_adapter_offset = state. metrics . access_adapter_offset ;
85
- let debug_info = state. metrics . debug_infos . get ( pc) ;
78
+ let debug_info = state. metrics . debug_infos . get ( prev_pc) ;
86
79
let dsl_instr = debug_info. as_ref ( ) . map ( |info| info. dsl_instruction . clone ( ) ) ;
87
80
88
- let now_trace_heights = get_dyn_trace_heights_from_arenas :: < F , _ > (
89
- num_sys_airs,
90
- access_adapter_offset,
91
- & state. memory . access_adapter_records ,
92
- & state. ctx . arenas ,
93
- ) ;
94
- let mut now_trace_cells = now_trace_heights;
95
-
96
- let metrics = & mut state. metrics ;
97
- for ( main_width, cell_count) in zip ( & metrics. main_widths , & mut now_trace_cells) {
98
- * cell_count *= main_width;
99
- }
100
- metrics. update_trace_cells ( now_trace_cells, opcode_name, dsl_instr) ;
101
-
102
- metrics. update_current_fn ( pc) ;
81
+ let now_trace_heights: Vec < usize > = state
82
+ . ctx
83
+ . arenas
84
+ . iter ( )
85
+ . map ( |arena| arena. current_trace_height ( ) )
86
+ . collect ( ) ;
87
+ let now_trace_cells = zip ( & state. metrics . main_widths , & now_trace_heights)
88
+ . map ( |( main_width, h) | main_width * h)
89
+ . collect_vec ( ) ;
90
+ state
91
+ . metrics
92
+ . update_trace_cells ( now_trace_cells, opcode_name, dsl_instr) ;
93
+
94
+ state. metrics . update_current_fn ( pc) ;
103
95
}
104
96
}
105
97
106
- /// Assumed that `record_arenas` has length equal to number of AIRs.
107
- ///
108
- /// Best effort calculation of the used trace heights per chip without padding to powers of
109
- /// two. This is best effort because some periphery chips may not have record arenas
110
- /// to instrument.
111
- ///
112
- /// Does not include constant trace heights or the used program trace height.
113
- pub ( crate ) fn get_dyn_trace_heights_from_arenas < F , RA > (
114
- num_sys_airs : usize ,
115
- access_adapter_offset : usize ,
116
- access_adapter_records : & DenseRecordArena ,
117
- record_arenas : & [ RA ] ,
118
- ) -> Vec < usize >
98
+ // Memory access adapter height calculation is slow, so only do it if this is the end of
99
+ // execution.
100
+ // We also clear the current trace cell counts so there aren't negative diffs at the start of the
101
+ // next segment.
102
+ #[ cfg( feature = "perf-metrics" ) ]
103
+ pub fn end_segment_metrics < F , RA > ( state : & mut VmExecState < F , TracingMemory , TracegenCtx < RA > > )
119
104
where
120
105
F : Clone + Send + Sync ,
121
106
RA : Arena ,
122
107
{
123
- // First, get used heights from record arenas
124
- let mut heights : Vec < usize > = record_arenas
125
- . iter ( )
126
- . map ( |arena| arena . current_trace_height ( ) )
127
- . collect ( ) ;
128
- // Memory is special case, so extract the memory AIR's trace heights from the special
129
- // arena
108
+ use std :: iter :: zip ;
109
+
110
+ use crate :: system :: memory :: adapter :: AccessAdapterInventory ;
111
+
112
+ let access_adapter_offset = state . metrics . access_adapter_offset ;
113
+ let num_sys_airs = state . metrics . num_sys_airs ;
114
+ let mut now_heights = vec ! [ 0 ; num_sys_airs - access_adapter_offset ] ;
130
115
AccessAdapterInventory :: < F > :: compute_heights_from_arena (
131
- access_adapter_records,
132
- & mut heights [ access_adapter_offset..num_sys_airs ] ,
116
+ & state . memory . access_adapter_records ,
117
+ & mut now_heights ,
133
118
) ;
134
-
135
- heights
119
+ let now_trace_cells = zip (
120
+ & state. metrics . main_widths [ access_adapter_offset..] ,
121
+ & now_heights,
122
+ )
123
+ . map ( |( main_width, h) | main_width * h)
124
+ . collect_vec ( ) ;
125
+ for ( air_name, & now_value) in itertools:: izip!(
126
+ & state. metrics. air_names[ access_adapter_offset..] ,
127
+ & now_trace_cells,
128
+ ) {
129
+ if now_value != 0 {
130
+ let labels = [
131
+ ( "air_name" , air_name. clone ( ) ) ,
132
+ ( "opcode" , String :: default ( ) ) ,
133
+ ( "dsl_ir" , String :: default ( ) ) ,
134
+ ( "cycle_tracker_span" , "memory_access_adapters" . to_owned ( ) ) ,
135
+ ] ;
136
+ counter ! ( "cells_used" , & labels) . increment ( now_value as u64 ) ;
137
+ }
138
+ }
139
+ state. metrics . current_trace_cells . fill ( 0 ) ;
136
140
}
137
141
138
142
impl VmMetrics {
@@ -151,6 +155,7 @@ impl VmMetrics {
151
155
self . air_names = air_names;
152
156
self . main_widths = main_widths;
153
157
self . total_widths = total_widths;
158
+ self . current_trace_cells = vec ! [ 0 ; self . air_names. len( ) ] ;
154
159
}
155
160
156
161
pub fn update_trace_cells (
0 commit comments