scx_layered: Add stats for adjusted layer weights

Add stats for infeasible weights adjusted layer stats.

Signed-off-by: Daniel Hodges <hodges.daniel.scott@gmail.com>
This commit is contained in:
Daniel Hodges 2024-09-20 06:24:24 -04:00
parent da38d69009
commit 07be9dcf59
2 changed files with 37 additions and 7 deletions

View File

@ -76,6 +76,7 @@ const NR_GSTATS: usize = bpf_intf::global_stat_idx_NR_GSTATS as usize;
const NR_LSTATS: usize = bpf_intf::layer_stat_idx_NR_LSTATS as usize;
const NR_LAYER_MATCH_KINDS: usize = bpf_intf::layer_match_kind_NR_LAYER_MATCH_KINDS as usize;
const CORE_CACHE_LEVEL: u32 = 2;
const MIN_LAYER_WEIGHT: u32 = 1;
#[rustfmt::skip]
lazy_static::lazy_static! {
@ -733,6 +734,10 @@ struct Stats {
total_load: f64,
layer_loads: Vec<f64>,
// infeasible stats
total_dcycle_sum: f64,
total_load_sum: f64,
total_util: f64, // Running AVG of sum of layer_utils
layer_utils: Vec<f64>,
prev_layer_cycles: Vec<u64>,
@ -800,6 +805,9 @@ impl Stats {
total_load: 0.0,
layer_loads: vec![0.0; nr_layers],
total_dcycle_sum: 0.0,
total_load_sum: 0.0,
total_util: 0.0,
layer_utils: vec![0.0; nr_layers],
prev_layer_cycles: Self::read_layer_cycles(&cpu_ctxs, nr_layers),
@ -836,6 +844,14 @@ impl Stats {
.take(self.nr_layers)
.map(|layer| layer.nr_tasks as usize)
.collect();
let layer_weights: Vec<usize> = skel
.maps
.bss_data
.layers
.iter()
.take(self.nr_layers)
.map(|layer| layer.weight as usize)
.collect();
let layer_slice_us: Vec<u64> = skel
.maps
@ -849,7 +865,7 @@ impl Stats {
let (total_load, layer_loads) = Self::read_layer_loads(skel, self.nr_layers);
let cur_layer_cycles = Self::read_layer_cycles(&cpu_ctxs, self.nr_layers);
cur_layer_cycles.iter().enumerate().map(|(layer_idx, usage)| load_agg.record_dom_load(layer_idx, 100/*weight*/, usage));
cur_layer_cycles.iter().zip(layer_weights).enumerate().map(|(layer_idx, (usage, weight))| load_agg.record_dom_load(layer_idx, weight, *usage as f64));
let cur_layer_utils: Vec<f64> = cur_layer_cycles
.iter()
.zip(self.prev_layer_cycles.iter())
@ -864,6 +880,7 @@ impl Stats {
})
.collect();
let load_ledger = load_agg.calculate();
let cur_total_cpu = read_total_cpu(proc_reader)?;
let cpu_busy = calc_util(&cur_total_cpu, &self.prev_total_cpu)?;
@ -883,6 +900,9 @@ impl Stats {
total_load,
layer_loads,
total_dcycle_sum: load_ledger.global_dcycle_sum(),
total_load_sum: load_ledger.global_load_sum(),
total_util: layer_utils.iter().sum(),
layer_utils: layer_utils.try_into().unwrap(),
prev_layer_cycles: cur_layer_cycles,
@ -1851,11 +1871,12 @@ impl<'a, 'b> Scheduler<'a, 'b> {
cpus_ranges: &mut Vec<(usize, usize)>,
) -> Result<SysStats> {
let bstats = &stats.bpf_stats;
let load_ledger = self.load_agg.calculate();
let mut sys_stats = SysStats::new(stats, bstats, self.cpu_pool.fallback_cpu)?;
let mut sys_stats = SysStats::new(stats, bstats, &load_ledger, self.cpu_pool.fallback_cpu)?;
for (lidx, (spec, layer)) in self.layer_specs.iter().zip(self.layers.iter()).enumerate() {
let layer_stats = LayerStats::new(lidx, layer, stats, bstats, cpus_ranges[lidx]);
let layer_stats = LayerStats::new(lidx, layer, &load_ledger, stats, bstats, cpus_ranges[lidx]);
sys_stats.layers.insert(spec.name.to_string(), layer_stats);
cpus_ranges[lidx] = (layer.nr_cpus, layer.nr_cpus);
}

View File

@ -18,6 +18,7 @@ use log::warn;
use scx_stats::prelude::*;
use scx_stats_derive::stat_doc;
use scx_stats_derive::Stats;
use scx_utils::LoadLedger;
use serde::Deserialize;
use serde::Serialize;
@ -55,6 +56,8 @@ pub struct LayerStats {
pub util_frac: f64,
#[stat(desc = "sum of weight * duty_cycle for tasks")]
pub load: f64,
#[stat(desc = "layer load sum adjusted for infeasible weights")]
pub load_adj: f64,
#[stat(desc = "fraction of total load")]
pub load_frac: f64,
#[stat(desc = "count of tasks")]
@ -149,6 +152,7 @@ impl LayerStats {
pub fn new(
lidx: usize,
layer: &Layer,
load_ledger: &LoadLedger,
stats: &Stats,
bstats: &BpfStats,
nr_cpus_range: (usize, usize),
@ -179,6 +183,7 @@ impl LayerStats {
util: stats.layer_utils[lidx] * 100.0,
util_frac: calc_frac(stats.layer_utils[lidx], stats.total_util),
load: stats.layer_loads[lidx],
load_adj: load_ledger.dom_load_sums()[lidx],
load_frac: calc_frac(stats.layer_loads[lidx], stats.total_load),
tasks: stats.nr_layer_tasks[lidx] as u32,
total: ltotal,
@ -221,11 +226,12 @@ impl LayerStats {
pub fn format<W: Write>(&self, w: &mut W, name: &str, header_width: usize) -> Result<()> {
writeln!(
w,
" {:<width$}: util/frac={:7.1}/{:5.1} load/frac={:9.1}/{:5.1} tasks={:6}",
" {:<width$}: util/frac={:7.1}/{:5.1} load/load_adj/frac={:9.1}/{:9.1}/{:5.1} tasks={:6}",
name,
self.util,
self.util_frac,
self.load,
self.load_adj,
self.load_frac,
self.tasks,
width = header_width,
@ -364,6 +370,8 @@ pub struct SysStats {
pub util: f64,
#[stat(desc = "sum of weight * duty_cycle for all tasks")]
pub load: f64,
#[stat(desc = "adjusted load for all tasks with infeasible weights applied")]
pub load_adj: f64,
#[stat(desc = "fallback CPU")]
pub fallback_cpu: u32,
#[stat(desc = "per-layer statistics")]
@ -371,7 +379,7 @@ pub struct SysStats {
}
impl SysStats {
pub fn new(stats: &Stats, bstats: &BpfStats, fallback_cpu: usize) -> Result<Self> {
pub fn new(stats: &Stats, bstats: &BpfStats, load_ledger: &LoadLedger, fallback_cpu: usize) -> Result<Self> {
let lsum = |idx| stats.bpf_stats.lstats_sums[idx as usize];
let total = lsum(bpf_intf::layer_stat_idx_LSTAT_SEL_LOCAL)
+ lsum(bpf_intf::layer_stat_idx_LSTAT_ENQ_WAKEUP)
@ -401,6 +409,7 @@ impl SysStats {
busy: stats.cpu_busy * 100.0,
util: stats.total_util * 100.0,
load: stats.total_load,
load_adj: load_ledger.global_load_sum(),
fallback_cpu: fallback_cpu as u32,
layers: BTreeMap::new(),
})
@ -419,8 +428,8 @@ impl SysStats {
writeln!(
w,
"busy={:5.1} util={:7.1} load={:9.1} fallback_cpu={:3}",
self.busy, self.util, self.load, self.fallback_cpu,
"busy={:5.1} util={:7.1} load={:9.1} load_adj={:9.1} fallback_cpu={:3}",
self.busy, self.util, self.load, self.load_adj, self.fallback_cpu,
)?;
writeln!(