Profiling
Profiling in ZisK is cost-accurate: every instruction executed inside a labeled region is counted and attributed to that region. Use the profiling macros to identify which parts of your guest program drive up cost or step count before they become expensive at scale.
Overview
Profiling attributes proving work to specific regions of guest code. You wrap a region and the work spent inside is recorded against that label, so you can see which parts of a program dominate proof generation. Two quantities are measurable:
| Quantity | Description |
|---|---|
| Cost | Proving work for the region, weighted by instruction mix. |
| Steps | Raw RISC-V instruction count for the region. |
Accumulated report
These macros record region boundaries in the execution trace. Nothing is printed at runtime; the external profiler tool reads the trace after the run and accumulates results across regions.
profile_report
The pair profile_report_start! / profile_report_end! opens and
closes a named region whose proving cost is recorded in the
execution trace.
profile_report_start!(LABEL)
// code to be profiled.
profile_report_end!(LABEL)
Parameters
| Name | Type | Description |
|---|---|---|
label | identifier | A bare identifier that names the region. The matching profile_end! must be called with the same identifier. |
Example
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
ziskos::profile_report_start!(HASH_LOOP);
for value in &input.values {
hasher.update(value.to_le_bytes());
}
let digest = hasher.finalize();
ziskos::profile_report_end!(HASH_LOOP);
profile_report_steps
The pair profile_report_steps_start! / profile_report_steps_end!
opens and closes a named region whose RISC-V step count is recorded
in the execution trace.
profile_report_steps_start!(label)
// code to be profiled.
profile_report_steps_end!(label)
Example
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
ziskos::profile_report_steps_start!(HASH_LOOP);
for value in &input.values {
hasher.update(value.to_le_bytes());
}
let digest = hasher.finalize();
ziskos::profile_report_steps_end!(HASH_LOOP);
Inline reports
These macros also record the region in the trace, but print the measurement every time the program runs.
profile
The pair profile_start! / profile_end! works like
profile_report, but prints the proving cost at region close in
addition to recording it in the trace.
profile_start!(label)
// code to be profiled.
profile_end!(label)
Example
use sha2::{Digest, Sha256};
let mut state: [u8; 32] = [0u8; 32];
for value in &input.values {
ziskos::profile_start!(ROLLING_HASH);
let mut hasher = Sha256::new();
hasher.update(&state);
hasher.update(value.to_le_bytes());
state = hasher.finalize().into();
ziskos::profile_end!(ROLLING_HASH);
}
profile_steps
The pair profile_steps_start! / profile_steps_end! works like
profile_report_steps, but prints the step count at region close
in addition to recording it in the trace.
profile_steps_start!(label)
// code to be profiled.
profile_steps_end!(label)
Example
use sha2::{Digest, Sha256};
let mut state: [u8; 32] = [0u8; 32];
for value in &input.values {
ziskos::profile_steps_start!(ROLLING_HASH);
let mut hasher = Sha256::new();
hasher.update(&state);
hasher.update(value.to_le_bytes());
state = hasher.finalize().into();
ziskos::profile_steps_end!(ROLLING_HASH);
}
Regions must be properly nested. Calling an end macro with a label
that has no matching open start produces undefined behavior in the
profiler output.