use super::*;
#[derive(Debug, Clone, serde::Serialize)]
#[non_exhaustive]
pub struct MetricDef {
pub name: &'static str,
pub polarity: crate::test_support::Polarity,
pub kind: MetricKind,
pub default_abs: f64,
pub default_rel: f64,
pub display_unit: &'static str,
#[serde(skip)]
pub accessor: fn(&GauntletRow) -> Option<f64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
#[non_exhaustive]
pub enum MetricKind {
Counter,
Gauge(GaugeAgg),
Peak,
Timestamp,
DeltaSum,
PerPhaseDeltaSum,
Rate {
numerator: &'static str,
denominator: &'static str,
},
Distribution {
source: SampleSource,
reduction: SampleReduction,
},
WorstLowest {
numerator: WorstLowestNumerator,
denominator: WorstLowestDenominator,
},
WakeLatencyTailRatio,
WorstCrossNodeRatio,
#[allow(clippy::doc_lazy_continuation)]
PerPhase,
PerRunDistribution,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
#[non_exhaustive]
pub enum GaugeAgg {
Avg,
Last,
Max,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
#[non_exhaustive]
#[allow(clippy::enum_variant_names)]
pub enum SampleSource {
WakeLatencyNs,
RunDelayNs,
TimerLatencyNs,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
#[non_exhaustive]
pub enum SampleReduction {
P99,
P999,
Median,
Cv,
Mean,
Worst,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
#[non_exhaustive]
pub enum WorstLowestNumerator {
Iterations,
NumaLocal,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
#[non_exhaustive]
pub enum WorstLowestDenominator {
NumWorkers,
CpuTimeNs,
NumaTotal,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum MergeKind {
Commutative,
NonCommutative,
Recompute,
}
impl MetricKind {
pub fn merge_kind(self) -> MergeKind {
match self {
MetricKind::Counter => MergeKind::Commutative,
MetricKind::Peak => MergeKind::Commutative,
MetricKind::Gauge(GaugeAgg::Avg) => MergeKind::Commutative,
MetricKind::Gauge(GaugeAgg::Max) => MergeKind::Commutative,
MetricKind::Gauge(GaugeAgg::Last) => MergeKind::NonCommutative,
MetricKind::Timestamp => MergeKind::NonCommutative,
MetricKind::DeltaSum => MergeKind::Commutative,
MetricKind::PerPhaseDeltaSum => MergeKind::Commutative,
MetricKind::Rate { .. } => MergeKind::Recompute,
MetricKind::Distribution { .. } => MergeKind::Recompute,
MetricKind::WorstLowest { .. } => MergeKind::Recompute,
MetricKind::WakeLatencyTailRatio => MergeKind::Recompute,
MetricKind::WorstCrossNodeRatio => MergeKind::Recompute,
MetricKind::PerPhase => MergeKind::Recompute,
MetricKind::PerRunDistribution => MergeKind::Recompute,
}
}
pub fn is_derived(self) -> bool {
matches!(
self,
MetricKind::Rate { .. }
| MetricKind::Distribution { .. }
| MetricKind::WorstLowest { .. }
| MetricKind::WakeLatencyTailRatio
| MetricKind::WorstCrossNodeRatio
| MetricKind::PerPhase
| MetricKind::PerRunDistribution
)
}
}
pub fn aggregate_samples(samples: &[f64], kind: MetricKind) -> Option<f64> {
let finite: Vec<f64> = samples.iter().copied().filter(|x| x.is_finite()).collect();
aggregate_finite(&finite, |_| 1, kind)
}
pub fn aggregate_samples_weighted(pairs: &[(f64, usize)], kind: MetricKind) -> Option<f64> {
let finite: Vec<(f64, usize)> = pairs
.iter()
.copied()
.filter(|(x, _)| x.is_finite())
.collect();
if finite.is_empty() {
return None;
}
let values: Vec<f64> = finite.iter().map(|(x, _)| *x).collect();
aggregate_finite(&values, |i| finite[i].1, kind)
}
fn aggregate_finite(
finite: &[f64],
weight_for: impl Fn(usize) -> usize,
kind: MetricKind,
) -> Option<f64> {
if finite.is_empty() {
return None;
}
Some(match kind {
MetricKind::Counter | MetricKind::DeltaSum => finite.iter().sum(),
MetricKind::PerPhaseDeltaSum => finite.iter().sum::<f64>() / (finite.len() as f64),
MetricKind::Distribution {
reduction: SampleReduction::Worst,
..
} => finite.iter().copied().fold(f64::NEG_INFINITY, f64::max),
MetricKind::Distribution { .. }
| MetricKind::WorstLowest { .. }
| MetricKind::WakeLatencyTailRatio
| MetricKind::WorstCrossNodeRatio => finite.iter().sum::<f64>() / (finite.len() as f64),
MetricKind::Gauge(GaugeAgg::Avg) => {
let total_weight: usize = finite
.iter()
.enumerate()
.try_fold(0usize, |acc, (i, _)| acc.checked_add(weight_for(i)))
.unwrap_or(0);
if total_weight == 0 {
finite.iter().sum::<f64>() / (finite.len() as f64)
} else {
finite
.iter()
.enumerate()
.map(|(i, x)| *x * (weight_for(i) as f64))
.sum::<f64>()
/ (total_weight as f64)
}
}
MetricKind::Gauge(GaugeAgg::Last) | MetricKind::Timestamp => {
*finite.last().expect("non-empty by check above")
}
MetricKind::Gauge(GaugeAgg::Max) | MetricKind::Peak => {
finite.iter().copied().fold(f64::NEG_INFINITY, f64::max)
}
MetricKind::Rate { .. } => unreachable!(
"MetricKind::Rate must be derived via derive_rate_metrics, \
not reduced from a sample slice"
),
MetricKind::PerPhase => unreachable!(
"MetricKind::PerPhase is derived by derive_phase_metrics, \
not reduced from a sample slice"
),
MetricKind::PerRunDistribution => unreachable!(
"MetricKind::PerRunDistribution is produced by \
populate_run_pooled_schbench_distribution / populate_run_pooled_taobench_distribution \
and noise-compared per-run, not reduced from a sample slice"
),
})
}
pub fn aggregate_samples_for_phase(metric: &MetricDef, samples: &[f64]) -> Option<f64> {
match metric.kind {
MetricKind::Counter => phase_counter_delta(samples),
k if k.is_derived() => None,
_ => aggregate_samples(samples, metric.kind),
}
}
pub fn phase_counter_delta(samples: &[f64]) -> Option<f64> {
let finite: Vec<f64> = samples.iter().copied().filter(|x| x.is_finite()).collect();
match finite.as_slice() {
[] | [_] => None,
[first, .., last] => {
let delta = *last - *first;
if delta < 0.0 {
tracing::warn!(
first = *first,
last = *last,
"phase_counter_delta: counter reset detected (last < first); clamping to 0"
);
Some(0.0)
} else {
Some(delta)
}
}
}
}
pub(crate) fn derive_rate_metrics(metrics: &mut std::collections::BTreeMap<String, f64>) {
derive_rate_metrics_from(
metrics,
METRICS.iter().filter_map(|m| match m.kind {
MetricKind::Rate {
numerator,
denominator,
} => Some((m.name, numerator, denominator)),
_ => None,
}),
);
}
pub(crate) fn derive_rate_metrics_from<'a>(
metrics: &mut std::collections::BTreeMap<String, f64>,
rates: impl Iterator<Item = (&'a str, &'a str, &'a str)>,
) {
for (name, numerator, denominator) in rates {
let (Some(num), Some(den)) = (
metrics.get(numerator).copied(),
metrics.get(denominator).copied(),
) else {
continue;
};
if num.is_finite() && den.is_finite() && den != 0.0 {
let rate = num / den;
if rate.is_finite() {
metrics.insert(name.to_string(), rate);
}
}
}
}
impl MetricDef {
pub fn read(&self, row: &GauntletRow) -> Option<f64> {
(self.accessor)(row).or_else(|| row.ext_metrics.get(self.name).copied())
}
pub fn read_sample(&self, sample: &crate::scenario::sample::Sample<'_>) -> Option<f64> {
match self.name {
"max_dsq_depth" => sample
.snapshot
.dsq_states()
.iter()
.filter(|d| d.origin.starts_with("local cpu "))
.map(|d| u64::from(d.nr))
.max()
.map(|v| v as f64),
"avg_dsq_depth" => {
let locals: Vec<f64> = sample
.snapshot
.dsq_states()
.iter()
.filter(|d| d.origin.starts_with("local cpu "))
.map(|d| u64::from(d.nr) as f64)
.collect();
if locals.is_empty() {
None
} else {
Some(locals.iter().sum::<f64>() / locals.len() as f64)
}
}
"total_fallback" => sample
.snapshot
.event_counter_timeline()
.last()
.map(|e| e.select_cpu_fallback as f64),
"total_keep_last" => sample
.snapshot
.event_counter_timeline()
.last()
.map(|e| e.dispatch_keep_last as f64),
"total_hardirqs" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.irqs_sum)
.fold(0u64, u64::saturating_add) as f64
})
}
"total_softirq_net_rx" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.softirqs[crate::monitor::btf_offsets::SOFTIRQ_NET_RX])
.fold(0u64, u64::saturating_add) as f64
})
}
"total_softirq_net_tx" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.softirqs[crate::monitor::btf_offsets::SOFTIRQ_NET_TX])
.fold(0u64, u64::saturating_add) as f64
})
}
"total_softirq_timer" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.softirqs[crate::monitor::btf_offsets::SOFTIRQ_TIMER])
.fold(0u64, u64::saturating_add) as f64
})
}
"total_softirq_sched" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.softirqs[crate::monitor::btf_offsets::SOFTIRQ_SCHED])
.fold(0u64, u64::saturating_add) as f64
})
}
"total_irq_time_ns" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.cpustat_irq_ns)
.fold(0u64, u64::saturating_add) as f64
})
}
"total_softirq_time_ns" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.cpustat_softirq_ns)
.fold(0u64, u64::saturating_add) as f64
})
}
"total_steal_time_ns" => {
let cpus = sample.snapshot.per_cpu_time();
(!cpus.is_empty()).then(|| {
cpus.iter()
.map(|c| c.cpustat_steal_ns)
.fold(0u64, u64::saturating_add) as f64
})
}
_ => None,
}
}
pub const fn higher_is_worse(&self) -> bool {
use crate::test_support::Polarity;
matches!(
self.polarity,
Polarity::LowerBetter | Polarity::TargetValue(_) | Polarity::Unknown
)
}
pub const fn classify_direction(&self) -> Option<bool> {
self.polarity.classify_direction()
}
pub const fn gates_aggregate(&self, noise_adjust: bool) -> bool {
match self.kind {
MetricKind::PerPhase => false,
MetricKind::PerRunDistribution => noise_adjust,
_ => true,
}
}
}
pub(crate) const SCHBENCH_WAKEUP_P50_US: &str = "wakeup_p50_latency_us";
pub(crate) const SCHBENCH_WAKEUP_P90_US: &str = "wakeup_p90_latency_us";
pub(crate) const SCHBENCH_WAKEUP_P99_US: &str = "wakeup_p99_latency_us";
pub(crate) const SCHBENCH_WAKEUP_P999_US: &str = "wakeup_p999_latency_us";
pub(crate) const SCHBENCH_REQUEST_P50_US: &str = "request_p50_latency_us";
pub(crate) const SCHBENCH_REQUEST_P90_US: &str = "request_p90_latency_us";
pub(crate) const SCHBENCH_REQUEST_P99_US: &str = "request_p99_latency_us";
pub(crate) const SCHBENCH_REQUEST_P999_US: &str = "request_p999_latency_us";
pub(crate) const SCHBENCH_SCHED_DELAY_MSG_US: &str = "sched_delay_msg_us";
pub(crate) const SCHBENCH_SCHED_DELAY_WORKER_US: &str = "sched_delay_worker_us";
pub(crate) const SCHBENCH_LOOP_COUNT: &str = "schbench_loop_count";
pub(crate) const TOTAL_SCHBENCH_MSG_RUN_DELAY_NS: &str = "total_schbench_msg_run_delay_ns";
pub(crate) const TOTAL_SCHBENCH_MSG_PCOUNT: &str = "total_schbench_msg_pcount";
pub(crate) const TOTAL_SCHBENCH_WORKER_RUN_DELAY_NS: &str = "total_schbench_worker_run_delay_ns";
pub(crate) const TOTAL_SCHBENCH_WORKER_PCOUNT: &str = "total_schbench_worker_pcount";
pub(crate) const TOTAL_SCHBENCH_LOOPS: &str = "total_schbench_loops";
pub(crate) const SCHBENCH_MSG_RUN_DELAY_NS_PER_SCHED: &str = "schbench_msg_run_delay_ns_per_sched";
pub(crate) const SCHBENCH_WORKER_RUN_DELAY_NS_PER_SCHED: &str =
"schbench_worker_run_delay_ns_per_sched";
pub(crate) const SCHBENCH_WAKEUP_P50_US_WHOLE: &str = "wakeup_p50_latency_us_whole";
pub(crate) const SCHBENCH_WAKEUP_P90_US_WHOLE: &str = "wakeup_p90_latency_us_whole";
pub(crate) const SCHBENCH_WAKEUP_P99_US_WHOLE: &str = "wakeup_p99_latency_us_whole";
pub(crate) const SCHBENCH_WAKEUP_P999_US_WHOLE: &str = "wakeup_p999_latency_us_whole";
pub(crate) const SCHBENCH_WAKEUP_MIN_US_WHOLE: &str = "wakeup_min_latency_us_whole";
pub(crate) const SCHBENCH_WAKEUP_MAX_US_WHOLE: &str = "wakeup_max_latency_us_whole";
pub(crate) const SCHBENCH_REQUEST_P50_US_WHOLE: &str = "request_p50_latency_us_whole";
pub(crate) const SCHBENCH_REQUEST_P90_US_WHOLE: &str = "request_p90_latency_us_whole";
pub(crate) const SCHBENCH_REQUEST_P99_US_WHOLE: &str = "request_p99_latency_us_whole";
pub(crate) const SCHBENCH_REQUEST_P999_US_WHOLE: &str = "request_p999_latency_us_whole";
pub(crate) const SCHBENCH_REQUEST_MIN_US_WHOLE: &str = "request_min_latency_us_whole";
pub(crate) const SCHBENCH_REQUEST_MAX_US_WHOLE: &str = "request_max_latency_us_whole";
pub(crate) const SCHBENCH_RPS_P20_WHOLE: &str = "rps_p20_whole";
pub(crate) const SCHBENCH_RPS_P50_WHOLE: &str = "rps_p50_whole";
pub(crate) const SCHBENCH_RPS_P90_WHOLE: &str = "rps_p90_whole";
pub(crate) const SCHBENCH_RPS_MIN_WHOLE: &str = "rps_min_whole";
pub(crate) const SCHBENCH_RPS_MAX_WHOLE: &str = "rps_max_whole";
pub(crate) const TAOBENCH_TOTAL_QPS: &str = "taobench_total_qps";
pub(crate) const TAOBENCH_FAST_QPS: &str = "taobench_fast_qps";
pub(crate) const TAOBENCH_SLOW_QPS: &str = "taobench_slow_qps";
pub(crate) const TAOBENCH_HIT_RATIO: &str = "taobench_hit_ratio";
pub(crate) const TAOBENCH_HIT_RATE: &str = "taobench_hit_rate";
pub(crate) const TAOBENCH_SERVE_P50_US: &str = "taobench_serve_p50_us";
pub(crate) const TAOBENCH_SERVE_P90_US: &str = "taobench_serve_p90_us";
pub(crate) const TAOBENCH_SERVE_P99_US: &str = "taobench_serve_p99_us";
pub(crate) const TAOBENCH_SERVE_P999_US: &str = "taobench_serve_p999_us";
pub(crate) const TAOBENCH_SERVE_MIN_US: &str = "taobench_serve_min_us";
pub(crate) const TAOBENCH_SERVE_MAX_US: &str = "taobench_serve_max_us";
pub(crate) const TOTAL_TAOBENCH_OPS: &str = "total_taobench_ops";
pub(crate) const TOTAL_TAOBENCH_FAST_OPS: &str = "total_taobench_fast_ops";
pub(crate) const TOTAL_TAOBENCH_SLOW_OPS: &str = "total_taobench_slow_ops";
pub(crate) const TOTAL_TAOBENCH_WALL_SEC: &str = "total_taobench_wall_sec";
pub(crate) const TAOBENCH_TOTAL_OPS_PER_SEC: &str = "taobench_total_ops_per_sec";
pub(crate) const TAOBENCH_FAST_OPS_PER_SEC: &str = "taobench_fast_ops_per_sec";
pub(crate) const TAOBENCH_SLOW_OPS_PER_SEC: &str = "taobench_slow_ops_per_sec";
pub(crate) const TAOBENCH_HIT_FRACTION: &str = "taobench_hit_fraction";
pub(crate) const TAOBENCH_SERVE_P50_US_WHOLE: &str = "taobench_serve_p50_us_whole";
pub(crate) const TAOBENCH_SERVE_P90_US_WHOLE: &str = "taobench_serve_p90_us_whole";
pub(crate) const TAOBENCH_SERVE_P99_US_WHOLE: &str = "taobench_serve_p99_us_whole";
pub(crate) const TAOBENCH_SERVE_P999_US_WHOLE: &str = "taobench_serve_p999_us_whole";
pub(crate) const TAOBENCH_SERVE_MIN_US_WHOLE: &str = "taobench_serve_min_us_whole";
pub(crate) const TAOBENCH_SERVE_MAX_US_WHOLE: &str = "taobench_serve_max_us_whole";
pub(crate) const TOTAL_TAOBENCH_GET_CMDS: &str = "total_taobench_get_cmds";
pub(crate) const TOTAL_TAOBENCH_GET_HITS: &str = "total_taobench_get_hits";
pub(crate) const TAOBENCH_COMMAND_HIT_RATE: &str = "taobench_command_hit_rate";
pub(crate) const SCHBENCH_WAKEUP_MIN_US: &str = "wakeup_min_latency_us";
pub(crate) const SCHBENCH_WAKEUP_MAX_US: &str = "wakeup_max_latency_us";
pub(crate) const SCHBENCH_REQUEST_MIN_US: &str = "request_min_latency_us";
pub(crate) const SCHBENCH_REQUEST_MAX_US: &str = "request_max_latency_us";
pub(crate) const SCHBENCH_RPS_P20: &str = "rps_p20";
pub(crate) const SCHBENCH_RPS_P50: &str = "rps_p50";
pub(crate) const SCHBENCH_RPS_P90: &str = "rps_p90";
pub(crate) const SCHBENCH_RPS_MIN: &str = "rps_min";
pub(crate) const SCHBENCH_RPS_MAX: &str = "rps_max";
pub static METRICS: &[MetricDef] = &[
MetricDef {
name: "worst_spread",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Last),
default_abs: 5.0,
default_rel: 0.25,
display_unit: "%",
accessor: |r| Some(r.spread),
},
MetricDef {
name: "worst_gap_ms",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 500.0,
default_rel: 0.50,
display_unit: "ms",
accessor: |r| Some(r.gap_ms as f64),
},
MetricDef {
name: "total_migrations",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Counter,
default_abs: 2.0,
default_rel: 0.30,
display_unit: "",
accessor: |r| Some(r.migrations as f64),
},
MetricDef {
name: "worst_migration_ratio",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Last),
default_abs: 0.05,
default_rel: 0.20,
display_unit: "",
accessor: |r| Some(r.migration_ratio),
},
MetricDef {
name: "max_imbalance_ratio",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 1.0,
default_rel: 0.25,
display_unit: "x",
accessor: |r| Some(r.imbalance_ratio),
},
MetricDef {
name: "avg_imbalance_ratio",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Avg),
default_abs: 0.5,
default_rel: 0.25,
display_unit: "x",
accessor: |_| None,
},
MetricDef {
name: "max_dsq_depth",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |r| Some(r.max_dsq_depth as f64),
},
MetricDef {
name: "avg_dsq_depth",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Avg),
default_abs: 5.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "stuck_count",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.50,
display_unit: "",
accessor: |r| Some(r.stuck_count),
},
MetricDef {
name: "total_fallback",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Counter,
default_abs: 5.0,
default_rel: 0.30,
display_unit: "",
accessor: |r| Some(r.fallback_count as f64),
},
MetricDef {
name: "total_keep_last",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Counter,
default_abs: 5.0,
default_rel: 0.30,
display_unit: "",
accessor: |r| Some(r.keep_last_count as f64),
},
MetricDef {
name: "total_run_delay",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1000.0,
default_rel: 0.10,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "total_pcount",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_sched_count",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_yld_count",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_sched_goidle",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_ttwu_count",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_ttwu_local",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_run_delay_ns_per_sched",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Rate {
numerator: "total_run_delay",
denominator: "total_pcount",
},
default_abs: 100.0,
default_rel: 0.15,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "ttwu_local_fraction",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Rate {
numerator: "total_ttwu_local",
denominator: "total_ttwu_count",
},
default_abs: 0.05,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "sched_goidle_fraction",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_sched_goidle",
denominator: "total_sched_count",
},
default_abs: 0.05,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_schedstat_wall_sec",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 0.1,
default_rel: 0.30,
display_unit: "s",
accessor: |_| None,
},
MetricDef {
name: "run_delay_per_sec",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Rate {
numerator: "total_run_delay",
denominator: "total_schedstat_wall_sec",
},
default_abs: 1000.0,
default_rel: 0.30,
display_unit: "ns/s",
accessor: |_| None,
},
MetricDef {
name: "pcount_per_sec",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_pcount",
denominator: "total_schedstat_wall_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "/s",
accessor: |_| None,
},
MetricDef {
name: "sched_count_per_sec",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_sched_count",
denominator: "total_schedstat_wall_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "/s",
accessor: |_| None,
},
MetricDef {
name: "yld_count_per_sec",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_yld_count",
denominator: "total_schedstat_wall_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "/s",
accessor: |_| None,
},
MetricDef {
name: "ttwu_count_per_sec",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_ttwu_count",
denominator: "total_schedstat_wall_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "/s",
accessor: |_| None,
},
MetricDef {
name: "sched_goidle_per_sec",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_sched_goidle",
denominator: "total_schedstat_wall_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "/s",
accessor: |_| None,
},
MetricDef {
name: "avg_nr_running",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Avg),
default_abs: 0.5,
default_rel: 0.20,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "worst_p99_wake_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::WakeLatencyNs,
reduction: SampleReduction::P99,
},
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "worst_median_wake_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::WakeLatencyNs,
reduction: SampleReduction::Median,
},
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "worst_wake_latency_cv",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::WakeLatencyNs,
reduction: SampleReduction::Cv,
},
default_abs: 0.10,
default_rel: 0.25,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "worst_p99_timer_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::TimerLatencyNs,
reduction: SampleReduction::P99,
},
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "worst_median_timer_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::TimerLatencyNs,
reduction: SampleReduction::Median,
},
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "worst_p999_timer_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::TimerLatencyNs,
reduction: SampleReduction::P999,
},
default_abs: 100.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "worst_timer_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::TimerLatencyNs,
reduction: SampleReduction::Worst,
},
default_abs: 200.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "iteration_rate",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Rate {
numerator: "total_phase_iterations",
denominator: "total_phase_duration_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "iter/s",
accessor: |_| None,
},
MetricDef {
name: "total_iterations",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 2.0,
default_rel: 0.10,
display_unit: "",
accessor: |r| Some(r.total_iterations as f64),
},
MetricDef {
name: "total_phase_iterations",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_phase_duration_sec",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.30,
display_unit: "s",
accessor: |_| None,
},
MetricDef {
name: "total_cpu_time_sec",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.30,
display_unit: "s",
accessor: |_| None,
},
MetricDef {
name: "total_iterations_pooled",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "iterations_per_cpu_sec",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Rate {
numerator: "total_iterations_pooled",
denominator: "total_cpu_time_sec",
},
default_abs: 10.0,
default_rel: 0.10,
display_unit: "iter/cpu-s",
accessor: |_| None,
},
MetricDef {
name: "system_time_ns",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhaseDeltaSum,
default_abs: 1000.0,
default_rel: 0.30,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "user_time_ns",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhaseDeltaSum,
default_abs: 1000.0,
default_rel: 0.30,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "total_hardirqs",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_softirq_net_rx",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_softirq_net_tx",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_softirq_timer",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_softirq_sched",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_irq_time_ns",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1000.0,
default_rel: 0.50,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "total_softirq_time_ns",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1000.0,
default_rel: 0.50,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "total_steal_time_ns",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1000.0,
default_rel: 0.50,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "avg_irq_util",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Avg),
default_abs: 20.0,
default_rel: 0.30,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "max_avg_irq_util",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 50.0,
default_rel: 0.30,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "hardirq_rate",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_hardirqs",
denominator: "total_phase_wall_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "irq/s",
accessor: |_| None,
},
MetricDef {
name: "net_rx_softirq_rate",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: "total_softirq_net_rx",
denominator: "total_phase_wall_sec",
},
default_abs: 1.0,
default_rel: 0.30,
display_unit: "softirq/s",
accessor: |_| None,
},
MetricDef {
name: "irq_time_fraction",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Rate {
numerator: "total_irq_time_ns",
denominator: "total_phase_wall_ns",
},
default_abs: 0.02,
default_rel: 0.30,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_phase_wall_sec",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 0.1,
default_rel: 0.30,
display_unit: "s",
accessor: |_| None,
},
MetricDef {
name: "total_phase_wall_ns",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1000.0,
default_rel: 0.30,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: "max_cpu_hardirqs",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Peak,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "max_cpu_hardirq_concentration",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 1.0,
default_rel: 0.25,
display_unit: "x",
accessor: |_| None,
},
MetricDef {
name: "max_cpu_softirq_net_rx",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Peak,
default_abs: 10.0,
default_rel: 0.50,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "max_cpu_softirq_net_rx_concentration",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 1.0,
default_rel: 0.25,
display_unit: "x",
accessor: |_| None,
},
MetricDef {
name: "avg_cpu_util_comp_scale",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Avg),
default_abs: 0.5,
default_rel: 0.30,
display_unit: "x",
accessor: |_| None,
},
MetricDef {
name: "avg_task_lat_cri",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Gauge(GaugeAgg::Avg),
default_abs: 50.0,
default_rel: 0.30,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "max_task_lat_cri",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Peak,
default_abs: 100.0,
default_rel: 0.30,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "max_cgroup_irq_pressure",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Peak,
default_abs: 1.0,
default_rel: 0.50,
display_unit: "µs",
accessor: |_| None,
},
MetricDef {
name: "max_cgroup_irq_pressure_concentration",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 1.0,
default_rel: 0.25,
display_unit: "x",
accessor: |_| None,
},
MetricDef {
name: "max_cgroup_psi_irq_avg10",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Peak,
default_abs: 5.0,
default_rel: 0.30,
display_unit: "%",
accessor: |_| None,
},
MetricDef {
name: "psi_irq_full_avg10",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Gauge(GaugeAgg::Avg),
default_abs: 5.0,
default_rel: 0.30,
display_unit: "%",
accessor: |_| None,
},
MetricDef {
name: "total_irq_pressure_us",
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.50,
display_unit: "µs",
accessor: |_| None,
},
MetricDef {
name: "worst_mean_run_delay_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::RunDelayNs,
reduction: SampleReduction::Mean,
},
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "worst_run_delay_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Distribution {
source: SampleSource::RunDelayNs,
reduction: SampleReduction::Worst,
},
default_abs: 100.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "worst_wake_latency_tail_ratio",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::WakeLatencyTailRatio,
default_abs: 0.5,
default_rel: 0.25,
display_unit: "x",
accessor: |_| None,
},
MetricDef {
name: "worst_iterations_per_worker",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::WorstLowest {
numerator: WorstLowestNumerator::Iterations,
denominator: WorstLowestDenominator::NumWorkers,
},
default_abs: 10.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "worst_iterations_per_cpu_sec",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::WorstLowest {
numerator: WorstLowestNumerator::Iterations,
denominator: WorstLowestDenominator::CpuTimeNs,
},
default_abs: 10.0,
default_rel: 0.10,
display_unit: "iter/cpu-s",
accessor: |_| None,
},
MetricDef {
name: "worst_page_locality",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::WorstLowest {
numerator: WorstLowestNumerator::NumaLocal,
denominator: WorstLowestDenominator::NumaTotal,
},
default_abs: 0.05,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "worst_cross_node_migration_ratio",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::WorstCrossNodeRatio,
default_abs: 0.05,
default_rel: 0.20,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P50_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P90_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P99_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P999_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P50_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P90_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P99_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P999_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_SCHED_DELAY_MSG_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_SCHED_DELAY_WORKER_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_LOOP_COUNT,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 1.0,
default_rel: 0.30,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_TOTAL_QPS,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "ops/s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_FAST_QPS,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "ops/s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SLOW_QPS,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "ops/s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_HIT_RATIO,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::PerPhase,
default_abs: 0.02,
default_rel: 0.05,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_HIT_RATE,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::PerPhase,
default_abs: 0.02,
default_rel: 0.05,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P50_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P90_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P99_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P999_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_MIN_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_MAX_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TOTAL_TAOBENCH_OPS,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TOTAL_TAOBENCH_FAST_OPS,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TOTAL_TAOBENCH_SLOW_OPS,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TOTAL_TAOBENCH_WALL_SEC,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.30,
display_unit: "s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_TOTAL_OPS_PER_SEC,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Rate {
numerator: TOTAL_TAOBENCH_OPS,
denominator: TOTAL_TAOBENCH_WALL_SEC,
},
default_abs: 10.0,
default_rel: 0.10,
display_unit: "ops/s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_FAST_OPS_PER_SEC,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Rate {
numerator: TOTAL_TAOBENCH_FAST_OPS,
denominator: TOTAL_TAOBENCH_WALL_SEC,
},
default_abs: 10.0,
default_rel: 0.10,
display_unit: "ops/s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SLOW_OPS_PER_SEC,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: TOTAL_TAOBENCH_SLOW_OPS,
denominator: TOTAL_TAOBENCH_WALL_SEC,
},
default_abs: 10.0,
default_rel: 0.10,
display_unit: "ops/s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_HIT_FRACTION,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: TOTAL_TAOBENCH_FAST_OPS,
denominator: TOTAL_TAOBENCH_OPS,
},
default_abs: 0.02,
default_rel: 0.05,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P50_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P90_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P99_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_P999_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_MIN_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_SERVE_MAX_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: TOTAL_TAOBENCH_GET_CMDS,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TOTAL_TAOBENCH_GET_HITS,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TAOBENCH_COMMAND_HIT_RATE,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Rate {
numerator: TOTAL_TAOBENCH_GET_HITS,
denominator: TOTAL_TAOBENCH_GET_CMDS,
},
default_abs: 0.02,
default_rel: 0.05,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TOTAL_SCHBENCH_MSG_RUN_DELAY_NS,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Counter,
default_abs: 1000.0,
default_rel: 0.10,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: TOTAL_SCHBENCH_MSG_PCOUNT,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TOTAL_SCHBENCH_WORKER_RUN_DELAY_NS,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Counter,
default_abs: 1000.0,
default_rel: 0.10,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: TOTAL_SCHBENCH_WORKER_PCOUNT,
polarity: crate::test_support::Polarity::Informational,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: TOTAL_SCHBENCH_LOOPS,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 1.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_MSG_RUN_DELAY_NS_PER_SCHED,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Rate {
numerator: TOTAL_SCHBENCH_MSG_RUN_DELAY_NS,
denominator: TOTAL_SCHBENCH_MSG_PCOUNT,
},
default_abs: 100.0,
default_rel: 0.10,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WORKER_RUN_DELAY_NS_PER_SCHED,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::Rate {
numerator: TOTAL_SCHBENCH_WORKER_RUN_DELAY_NS,
denominator: TOTAL_SCHBENCH_WORKER_PCOUNT,
},
default_abs: 100.0,
default_rel: 0.10,
display_unit: "ns",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_MIN_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_MAX_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_MIN_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_MAX_US,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_P20,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_P50,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_P90,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_MIN,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_MAX,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P50_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P90_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P99_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_P999_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_MIN_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_WAKEUP_MAX_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P50_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P90_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P99_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_P999_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_MIN_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_REQUEST_MAX_US_WHOLE,
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 50.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_P20_WHOLE,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_P50_WHOLE,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_P90_WHOLE,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_MIN_WHOLE,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: SCHBENCH_RPS_MAX_WHOLE,
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerRunDistribution,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "req/s",
accessor: |_| None,
},
MetricDef {
name: "p99_wake_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "median_wake_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "wake_latency_cv",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 0.10,
default_rel: 0.25,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "p99_timer_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "median_timer_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 20.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "p999_timer_latency_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 100.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "mean_run_delay_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 50.0,
default_rel: 0.25,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "max_run_delay_us",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 100.0,
default_rel: 0.50,
display_unit: "\u{00b5}s",
accessor: |_| None,
},
MetricDef {
name: "avg_off_cpu_pct",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 5.0,
default_rel: 0.25,
display_unit: "%",
accessor: |_| None,
},
MetricDef {
name: "min_off_cpu_pct",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 5.0,
default_rel: 0.25,
display_unit: "%",
accessor: |_| None,
},
MetricDef {
name: "max_off_cpu_pct",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 5.0,
default_rel: 0.25,
display_unit: "%",
accessor: |_| None,
},
MetricDef {
name: "off_cpu_spread_pct",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 5.0,
default_rel: 0.25,
display_unit: "%",
accessor: |_| None,
},
MetricDef {
name: "migration_ratio",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 0.05,
default_rel: 0.20,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "iterations_per_worker",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 10.0,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "page_locality",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::PerPhase,
default_abs: 0.05,
default_rel: 0.10,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "cross_node_migration_ratio",
polarity: crate::test_support::Polarity::LowerBetter,
kind: MetricKind::PerPhase,
default_abs: 0.05,
default_rel: 0.20,
display_unit: "",
accessor: |_| None,
},
MetricDef {
name: "total_cpu_time_ns",
polarity: crate::test_support::Polarity::HigherBetter,
kind: MetricKind::Counter,
default_abs: 100.0,
default_rel: 0.10,
display_unit: "ns",
accessor: |_| None,
},
];
pub const WAKE_LATENCY_TAIL_RATIO_MIN_ITERATIONS: u64 = 100;
pub fn metric_def(name: &str) -> Option<&'static MetricDef> {
METRICS.iter().find(|m| m.name == name)
}
const RENDER_SUPPRESSED_COMPONENTS: &[&str] = &[
"total_phase_iterations",
"total_phase_duration_sec",
"total_iterations_pooled",
"total_cpu_time_sec",
TOTAL_TAOBENCH_OPS,
TOTAL_TAOBENCH_FAST_OPS,
TOTAL_TAOBENCH_SLOW_OPS,
TOTAL_TAOBENCH_WALL_SEC,
TOTAL_TAOBENCH_GET_CMDS,
TOTAL_TAOBENCH_GET_HITS,
TOTAL_SCHBENCH_MSG_RUN_DELAY_NS,
TOTAL_SCHBENCH_MSG_PCOUNT,
TOTAL_SCHBENCH_WORKER_RUN_DELAY_NS,
TOTAL_SCHBENCH_WORKER_PCOUNT,
];
pub fn is_render_suppressed_component(name: &str) -> bool {
RENDER_SUPPRESSED_COMPONENTS.contains(&name)
}
pub fn infer_higher_is_worse(name: &str) -> bool {
const HIGHER_IS_WORSE_TOKENS: &[&str] = &[
"latency",
"delay",
"_gap",
"stall",
"stuck",
"_cv",
"error",
"fail",
"drop",
"spread",
"_us",
"_ms",
"_ns",
"migration_ratio",
"imbalance",
"_depth",
"dsq",
];
if HIGHER_IS_WORSE_TOKENS.iter().any(|t| name.contains(t)) {
return true;
}
const HIGHER_IS_BETTER_TOKENS: &[&str] = &[
"iops",
"throughput",
"bandwidth",
"iterations",
"ops_per_sec",
"locality",
"_score",
"goodput",
];
if HIGHER_IS_BETTER_TOKENS.iter().any(|t| name.contains(t)) {
return false;
}
true
}
pub fn list_metrics(json: bool) -> anyhow::Result<String> {
if json {
return serde_json::to_string_pretty(METRICS)
.map_err(|e| anyhow::anyhow!("serialize METRICS to JSON: {e}"));
}
let mut table = crate::cli::new_table();
table.set_header(vec![
"NAME",
"POLARITY",
"DEFAULT_ABS",
"DEFAULT_REL",
"UNIT",
]);
for m in METRICS {
table.add_row(vec![
m.name.to_string(),
polarity_label(m.polarity),
format!("{}", m.default_abs),
format!("{}", m.default_rel),
m.display_unit.to_string(),
]);
}
Ok(format!("{table}\n"))
}
fn polarity_label(p: crate::test_support::Polarity) -> String {
use crate::test_support::Polarity;
match p {
Polarity::HigherBetter => "higher".to_string(),
Polarity::LowerBetter => "lower".to_string(),
Polarity::TargetValue(t) => format!("target({t})"),
Polarity::Unknown => "unknown".to_string(),
Polarity::Informational => "informational".to_string(),
}
}