Skip to content

Commit

Permalink
Benchmark pov overhead
Browse files Browse the repository at this point in the history
Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
  • Loading branch information
ggwpez committed Aug 8, 2024
1 parent eb0a9e5 commit 2dad546
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 23 deletions.
41 changes: 29 additions & 12 deletions substrate/utils/frame/benchmarking-cli/src/extrinsic/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ pub struct BenchmarkParams {
/// Only useful for debugging.
#[arg(long)]
pub max_ext_per_block: Option<u32>,

/// Include the benchmarked proof size in the output.
#[arg(long)]
pub enable_proof_size: bool,
}

/// The results of multiple runs in nano seconds.
Expand Down Expand Up @@ -89,24 +93,28 @@ where
}

/// Benchmark a block with only inherents.
pub fn bench_block(&self) -> Result<Stats> {
let (block, _) = self.build_block(None)?;
///
/// Returns the Ref time stats and the proof size.
pub fn bench_block(&self) -> Result<(Stats, u64)> {
let (block, _, proof_size) = self.build_block(None)?;
let record = self.measure_block(&block)?;
Stats::new(&record)

Ok((Stats::new(&record)?, proof_size))
}

/// Benchmark the time of an extrinsic in a full block.
///
/// First benchmarks an empty block, analogous to `bench_block` and use it as baseline.
/// Then benchmarks a full block built with the given `ext_builder` and subtracts the baseline
/// from the result.
/// This is necessary to account for the time the inherents use.
pub fn bench_extrinsic(&self, ext_builder: &dyn ExtrinsicBuilder) -> Result<Stats> {
let (block, _) = self.build_block(None)?;
/// This is necessary to account for the time the inherents use. Returns ref time stats and the
/// proof size.
pub fn bench_extrinsic(&self, ext_builder: &dyn ExtrinsicBuilder) -> Result<(Stats, u64)> {
let (block, _, base_proof_size) = self.build_block(None)?;
let base = self.measure_block(&block)?;
let base_time = Stats::new(&base)?.select(StatSelect::Average);

let (block, num_ext) = self.build_block(Some(ext_builder))?;
let (block, num_ext, proof_size) = self.build_block(Some(ext_builder))?;
let num_ext = num_ext.ok_or_else(|| Error::Input("Block was empty".into()))?;
let mut records = self.measure_block(&block)?;

Expand All @@ -117,23 +125,24 @@ where
*r = ((*r as f64) / (num_ext as f64)).ceil() as u64;
}

Stats::new(&records)
Ok((Stats::new(&records)?, proof_size.saturating_sub(base_proof_size)))
}

/// Builds a block with some optional extrinsics.
///
/// Returns the block and the number of extrinsics in the block
/// that are not inherents.
/// that are not inherents together with the proof size.
/// Returns a block with only inherents if `ext_builder` is `None`.
fn build_block(
&self,
ext_builder: Option<&dyn ExtrinsicBuilder>,
) -> Result<(Block, Option<u64>)> {
) -> Result<(Block, Option<u64>, u64)> {
let chain = self.client.usage_info().chain;
let mut builder = BlockBuilderBuilder::new(&*self.client)
.on_parent_block(chain.best_hash)
.with_parent_block_number(chain.best_number)
.with_inherent_digests(Digest { logs: self.digest_items.clone() })
.enable_proof_recording()
.build()?;

// Create and insert the inherents.
Expand All @@ -146,7 +155,14 @@ where
let ext_builder = if let Some(ext_builder) = ext_builder {
ext_builder
} else {
return Ok((builder.build()?.block, None))
let proof_size = builder.estimate_block_size(true) - builder.estimate_block_size(false);
println!(
"HEYYYY: {}, with: {}, without: {}",
proof_size,
builder.estimate_block_size(true),
builder.estimate_block_size(false)
);
return Ok((builder.build()?.block, None, proof_size as u64))
};

// Put as many extrinsics into the block as possible and count them.
Expand All @@ -167,9 +183,10 @@ where
return Err("A Block must hold at least one extrinsic".into())
}
info!("Extrinsics per block: {}", num_ext);
let proof_size = builder.estimate_block_size(true) - builder.estimate_block_size(false);
let block = builder.build()?.block;

Ok((block, Some(num_ext)))
Ok((block, Some(num_ext), proof_size as u64))
}

/// Measures the time that it take to execute a block or an extrinsic.
Expand Down
15 changes: 11 additions & 4 deletions substrate/utils/frame/benchmarking-cli/src/overhead/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,23 @@ impl OverheadCmd {

// per-block execution overhead
{
let stats = bench.bench_block()?;
let (stats, proof_size) = bench.bench_block()?;
info!("Per-block execution overhead [ns]:\n{:?}", stats);
let template = TemplateData::new(BenchmarkType::Block, &cfg, &self.params, &stats)?;
let template =
TemplateData::new(BenchmarkType::Block, &cfg, &self.params, &stats, proof_size)?;
template.write(&self.params.weight.weight_path)?;
}
// per-extrinsic execution overhead
{
let stats = bench.bench_extrinsic(ext_builder)?;
let (stats, proof_size) = bench.bench_extrinsic(ext_builder)?;
info!("Per-extrinsic execution overhead [ns]:\n{:?}", stats);
let template = TemplateData::new(BenchmarkType::Extrinsic, &cfg, &self.params, &stats)?;
let template = TemplateData::new(
BenchmarkType::Extrinsic,
&cfg,
&self.params,
&stats,
proof_size,
)?;
template.write(&self.params.weight.weight_path)?;
}

Expand Down
13 changes: 9 additions & 4 deletions substrate/utils/frame/benchmarking-cli/src/overhead/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//! Converts a benchmark result into [`TemplateData`] and writes
//! it into the `weights.hbs` template.
use frame_support::pallet_prelude::Weight;
use sc_cli::Result;
use sc_service::Configuration;

Expand Down Expand Up @@ -59,8 +60,10 @@ pub(crate) struct TemplateData {
params: OverheadParams,
/// Stats about the benchmark result.
stats: Stats,
/// The resulting weight in ns.
weight: u64,
/// The resulting ref time weight.
ref_time: u64,
/// The size of the proof weight.
proof_size: u64,
}

impl TemplateData {
Expand All @@ -70,8 +73,9 @@ impl TemplateData {
cfg: &Configuration,
params: &OverheadParams,
stats: &Stats,
proof_size: u64,
) -> Result<Self> {
let weight = params.weight.calc_weight(stats)?;
let ref_time = params.weight.calc_weight(stats)?;
let header = params
.header
.as_ref()
Expand All @@ -91,7 +95,8 @@ impl TemplateData {
args: env::args().collect::<Vec<String>>(),
params: params.clone(),
stats: stats.clone(),
weight,
ref_time,
proof_size: params.bench.enable_proof_size.then(|| proof_size).unwrap_or(0),
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};

parameter_types! {
{{#if (eq short_name "block")}}
/// Time to execute an empty block.
/// Weight fo executing an empty block.
{{else}}
/// Time to execute a NO-OP extrinsic, for example `System::remark`.
/// Weight of executing a NO-OP extrinsic, for example `System::remark`.
{{/if}}
/// Calculated by multiplying the *{{params.weight.weight_metric}}* with `{{params.weight.weight_mul}}` and adding `{{params.weight.weight_add}}`.
///
Expand All @@ -35,7 +35,7 @@ parameter_types! {
/// 95th: {{underscore stats.p95}}
/// 75th: {{underscore stats.p75}}
pub const {{long_name}}Weight: Weight =
Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul({{underscore weight}}), 0);
Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul({{underscore ref_time}}), {{underscore proof_size}});
}

#[cfg(test)]
Expand Down

0 comments on commit 2dad546

Please sign in to comment.