Skip to content

Commit

Permalink
refactor: refactoring of perf metric related code.
Browse files Browse the repository at this point in the history
  • Loading branch information
anonymousGiga committed Mar 7, 2024
1 parent 8f529bd commit a3f1a68
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 600 deletions.
3 changes: 0 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions crates/perf-metrics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ tokio = { workspace = true, features = ["sync"] }
revm-utils = { workspace = true, optional = true }
revm = { workspace = true, optional = true }

ffi = { package = "reth-mdbx-sys", path = "../storage/libmdbx-rs/mdbx-sys" }
libc = "0.2"

[features]
enable_opcode_metrics = [
"revm-utils",
Expand Down
65 changes: 33 additions & 32 deletions crates/perf-metrics/src/dashboard/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,37 +38,14 @@ impl Default for CacheStats {
}
}

impl Print for CacheStats {
fn print_title(&self) {
println!("================================================ Metric of State ===========================================");
println!(
"{: <COL_WIDTH_BIG$}{:>COL_WIDTH_MIDDLE$}{:>COL_WIDTH_MIDDLE$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}",
"State functions", "Hits", "Misses", "Miss ratio (%)","Penalty time(s)", "Avg penalty (us)"
);
}

fn print_content(&self) {
self.print_item("blockhash", Function::BlockHash as usize);
self.print_item("code_by_hash", Function::CodeByHash as usize);
self.print_item("load_account/basic", Function::LoadCacheAccount as usize);
self.print_item("storage", Function::Storage as usize);
self.print_item("total", CACHE_STATS_LEN - 1);
}
}

trait StatsAndPrint {
fn stats(&self) -> CacheStats;
fn print_penalty_distribution(&self);
}

impl StatsAndPrint for CacheDbRecord {
fn stats(&self) -> CacheStats {
impl From<&CacheDbRecord> for CacheStats {
fn from(record: &CacheDbRecord) -> Self {
let mut cache_stats = CacheStats::default();

let total_stats = self.access_count();
let hit_stats = self.hit_stats();
let miss_stats = self.miss_stats();
let penalty_stats = self.penalty_stats();
let total_stats = record.access_count();
let hit_stats = record.hit_stats();
let miss_stats = record.miss_stats();
let penalty_stats = record.penalty_stats();

for index in 0..total_stats.function.len() {
cache_stats.functions[index].hits = hit_stats.function[index];
Expand All @@ -94,8 +71,32 @@ impl StatsAndPrint for CacheDbRecord {

cache_stats
}
}

impl Print for CacheStats {
fn print_title(&self) {
println!("================================================ Metric of State ===========================================");
println!(
"{: <COL_WIDTH_BIG$}{:>COL_WIDTH_MIDDLE$}{:>COL_WIDTH_MIDDLE$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}{:>COL_WIDTH_BIG$}",
"State functions", "Hits", "Misses", "Miss ratio (%)","Penalty time(s)", "Avg penalty (us)"
);
}

fn print_content(&self) {
self.print_item("blockhash", Function::BlockHash as usize);
self.print_item("code_by_hash", Function::CodeByHash as usize);
self.print_item("load_account/basic", Function::LoadCacheAccount as usize);
self.print_item("storage", Function::Storage as usize);
self.print_item("total", CACHE_STATS_LEN - 1);
}
}

trait PrintPenalty {
fn print_penalty(&self);
}

fn print_penalty_distribution(&self) {
impl PrintPenalty for CacheDbRecord {
fn print_penalty(&self) {
println!();
println!("================Penalty percentile=============");
self.penalty_stats().percentile.print_content();
Expand All @@ -105,8 +106,8 @@ impl StatsAndPrint for CacheDbRecord {

impl Print for CacheDbRecord {
fn print(&self, _block_number: u64) {
self.stats().print(_block_number);
self.print_penalty_distribution();
Into::<CacheStats>::into(self).print(_block_number);
self.print_penalty();
}
}

Expand Down
207 changes: 103 additions & 104 deletions crates/perf-metrics/src/dashboard/opcode.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
//! This module is used to support the display of opcode statistics metrics.
use super::commons::*;
use revm::revm_opcode::*;
use revm_utils::metrics::types::OpcodeRecord;
use revm_utils::{metrics::types::OpcodeRecord, time_utils::convert_cycles_to_ns_f64};
use std::collections::BTreeMap;

pub(crate) const OPCODE_NUMBER: usize = 256;
const MGAS_TO_GAS: u64 = 1_000_000u64;
const COL_WIDTH: usize = 15;
const OPCODE_NUMBER: usize = 256;

#[derive(Debug, Clone, Copy, Default)]
pub(crate) struct OpcodeInfo {
struct OpcodeInfo {
/// opcode category
pub(crate) category: &'static str,
category: &'static str,
/// gas fee
pub(crate) gas: u64,
gas: u64,
/// opcode cost a fixed gas fee?
pub(crate) static_gas: bool,
static_gas: bool,
}

pub(crate) const MERGE_MAP: [Option<(u8, OpcodeInfo)>; OPCODE_NUMBER] = [
const MERGE_MAP: [Option<(u8, OpcodeInfo)>; OPCODE_NUMBER] = [
Some((STOP, OpcodeInfo { category: "stop", gas: 0, static_gas: true })), //0x00
Some((ADD, OpcodeInfo { category: "arithmetic", gas: 3, static_gas: true })), //0x01
Some((MUL, OpcodeInfo { category: "arithmetic", gas: 5, static_gas: true })), //0x02
Expand Down Expand Up @@ -273,12 +277,6 @@ pub(crate) const MERGE_MAP: [Option<(u8, OpcodeInfo)>; OPCODE_NUMBER] = [
Some((SELFDESTRUCT, OpcodeInfo { category: "host", gas: 5000, static_gas: false })), //0xff
];

use super::commons::*;
use revm_utils::time_utils::convert_cycles_to_ns_f64;
use std::collections::BTreeMap;
const MGAS_TO_GAS: u64 = 1_000_000u64;

const COL_WIDTH: usize = 15;
#[derive(Default, Debug)]
struct OpcodeMergeRecord {
count: u64,
Expand Down Expand Up @@ -338,92 +336,6 @@ impl OpcodeStat {
}
}

#[derive(Debug)]
struct OpcodeStats {
overall: OpcodeStat,
opcode: [Option<OpcodeStat>; OPCODE_NUMBER],
merge_records: BTreeMap<&'static str, OpcodeMergeRecord>,
}

const ARRAY_REPEAT_VALUE: std::option::Option<OpcodeStat> = None;
impl Default for OpcodeStats {
fn default() -> Self {
Self {
overall: OpcodeStat::default(),
opcode: [ARRAY_REPEAT_VALUE; OPCODE_NUMBER],
merge_records: BTreeMap::new(),
}
}
}

impl OpcodeStats {
fn print_opcode_title(&self) {
println!("===========================================================================Metric of instruction======================================================================");
println!(
"{: <COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$} \
{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}",
"Opcode",
"Count",
"Count (%)",
"Time (s)",
"Time (%)",
"Cost (ns)",
"Total Mgas",
"Gas (%)",
"Static gas",
"Dyn. gas",
"Category"
);
}

fn print_opcodes(&self) {
println!();
self.print_opcode_title();
self.overall.print("overall");
for i in 0..OPCODE_NUMBER {
let name = OpCode::new(i as u8);
if name.is_none() {
continue
}
self.opcode[i]
.as_ref()
.expect("opcode record should not empty")
.print(name.unwrap().as_str());
}
println!();
}

fn print_category(&self) {
println!("\n");
println!("==========================================================================================");
println!(
"{:<COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}",
"Opcode Cat.", "Count", "Count (%)", "Time (s)", "Time (%)", "Cost (ns)",
);

for (k, v) in self.merge_records.iter() {
if *k == "" {
continue
}
println!(
"{:<COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$.2}{:>COL_WIDTH$.1}{:>COL_WIDTH$.3}{:>COL_WIDTH$.3}",
*k,
v.count,
v.count_pct * 100.0,
cycles_as_secs(v.time),
v.time_pct * 100.0,
v.avg_cost,
);
}
}
}

trait SupportPrint {
fn stats(&self) -> OpcodeStats;
fn print_addition_count(&self);
fn print_sload_percentile(&self);
}

// Return (total_gas, static_gas, dyn_gas).
fn caculate_gas(opcode: u8, count: u64, total_gas: i128) -> (f64, u64, f64) {
let (base_gas, is_static) = match MERGE_MAP[opcode as usize] {
Expand All @@ -449,11 +361,29 @@ fn category_name(opcode: u8) -> Option<&'static str> {
Some(MERGE_MAP[opcode as usize]?.1.category)
}

impl SupportPrint for OpcodeRecord {
fn stats(&self) -> OpcodeStats {
#[derive(Debug)]
struct OpcodeStats {
overall: OpcodeStat,
opcode: [Option<OpcodeStat>; OPCODE_NUMBER],
merge_records: BTreeMap<&'static str, OpcodeMergeRecord>,
}

const ARRAY_REPEAT_VALUE: std::option::Option<OpcodeStat> = None;
impl Default for OpcodeStats {
fn default() -> Self {
Self {
overall: OpcodeStat::default(),
opcode: [ARRAY_REPEAT_VALUE; OPCODE_NUMBER],
merge_records: BTreeMap::new(),
}
}
}

impl From<&OpcodeRecord> for OpcodeStats {
fn from(record: &OpcodeRecord) -> Self {
let mut opcode_stats = OpcodeStats::default();
// induction
for (i, v) in self.opcode_record.iter().enumerate() {
for (i, v) in record.opcode_record.iter().enumerate() {
// opcode
let op = i as u8;
let mut opcode_stat = OpcodeStat::default();
Expand Down Expand Up @@ -497,7 +427,7 @@ impl SupportPrint for OpcodeRecord {
}

// calculate opcode pct
for (i, _v) in self.opcode_record.iter().enumerate() {
for (i, _v) in record.opcode_record.iter().enumerate() {
opcode_stats.opcode[i].as_mut().expect("empty").count_pct =
opcode_stats.opcode[i].as_mut().expect("empty").count as f64 /
opcode_stats.overall.count as f64;
Expand All @@ -523,7 +453,76 @@ impl SupportPrint for OpcodeRecord {

opcode_stats
}
}

impl OpcodeStats {
fn print_opcode_title(&self) {
println!("===========================================================================Metric of instruction======================================================================");
println!(
"{: <COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$} \
{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}",
"Opcode",
"Count",
"Count (%)",
"Time (s)",
"Time (%)",
"Cost (ns)",
"Total Mgas",
"Gas (%)",
"Static gas",
"Dyn. gas",
"Category"
);
}

fn print_opcodes(&self) {
println!();
self.print_opcode_title();
self.overall.print("overall");
for i in 0..OPCODE_NUMBER {
let name = OpCode::new(i as u8);
if name.is_none() {
continue
}
self.opcode[i]
.as_ref()
.expect("opcode record should not empty")
.print(name.unwrap().as_str());
}
println!();
}

fn print_category(&self) {
println!("\n");
println!("==========================================================================================");
println!(
"{:<COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$}",
"Opcode Cat.", "Count", "Count (%)", "Time (s)", "Time (%)", "Cost (ns)",
);

for (k, v) in self.merge_records.iter() {
if *k == "" {
continue
}
println!(
"{:<COL_WIDTH$}{:>COL_WIDTH$}{:>COL_WIDTH$.2}{:>COL_WIDTH$.1}{:>COL_WIDTH$.3}{:>COL_WIDTH$.3}",
*k,
v.count,
v.count_pct * 100.0,
cycles_as_secs(v.time),
v.time_pct * 100.0,
v.avg_cost,
);
}
}
}

trait ExtraPrint {
fn print_addition_count(&self);
fn print_sload_percentile(&self);
}

impl ExtraPrint for OpcodeRecord {
fn print_addition_count(&self) {
println!();
println!("call additional rdtsc count: {}", self.additional_count[0]);
Expand All @@ -541,7 +540,7 @@ impl SupportPrint for OpcodeRecord {

impl Print for OpcodeRecord {
fn print(&self, _block_number: u64) {
let opcode_stats = self.stats();
let opcode_stats: OpcodeStats = self.into();
opcode_stats.print_opcodes();
opcode_stats.print_category();
self.print_addition_count();
Expand Down
Loading

0 comments on commit a3f1a68

Please sign in to comment.