scx_layered: Add layer growth config

Add a per layer config for different implementations of layer growth
algorithms. Convert the existing default logic into a default layer
growth algorithm and add a linear implementation.

Signed-off-by: Daniel Hodges <hodges.daniel.scott@gmail.com>
This commit is contained in:
Daniel Hodges 2024-08-28 19:17:24 -07:00
parent 7166f0085f
commit 7e0329e45c

View File

@ -94,6 +94,7 @@ lazy_static::lazy_static! {
preempt_first: false,
exclusive: false,
slice_us: 20000,
growth_algo: LayerGrowthAlgo::Sticky,
perf: 1024,
nodes: vec![],
llcs: vec![],
@ -113,6 +114,7 @@ lazy_static::lazy_static! {
preempt_first: false,
exclusive: true,
slice_us: 20000,
growth_algo: LayerGrowthAlgo::Sticky,
perf: 1024,
nodes: vec![],
llcs: vec![],
@ -131,6 +133,7 @@ lazy_static::lazy_static! {
preempt_first: false,
exclusive: false,
slice_us: 20000,
growth_algo: LayerGrowthAlgo::Linear,
perf: 1024,
nodes: vec![],
llcs: vec![],
@ -442,6 +445,17 @@ enum LayerMatch {
TGIDEquals(u32),
}
#[derive(Clone, Debug, Parser, Serialize, Deserialize)]
#[clap(rename_all = "snake_case")]
enum LayerGrowthAlgo {
Sticky,
Linear,
}
impl Default for LayerGrowthAlgo {
fn default() -> Self { LayerGrowthAlgo::Sticky }
}
#[derive(Clone, Debug, Serialize, Deserialize)]
enum LayerKind {
Confined {
@ -461,6 +475,8 @@ enum LayerKind {
#[serde(default)]
exclusive: bool,
#[serde(default)]
growth_algo: LayerGrowthAlgo,
#[serde(default)]
perf: u64,
#[serde(default)]
nodes: Vec<usize>,
@ -484,6 +500,8 @@ enum LayerKind {
#[serde(default)]
exclusive: bool,
#[serde(default)]
growth_algo: LayerGrowthAlgo,
#[serde(default)]
perf: u64,
#[serde(default)]
nodes: Vec<usize>,
@ -504,6 +522,8 @@ enum LayerKind {
#[serde(default)]
exclusive: bool,
#[serde(default)]
growth_algo: LayerGrowthAlgo,
#[serde(default)]
perf: u64,
#[serde(default)]
nodes: Vec<usize>,
@ -1067,6 +1087,48 @@ impl CpuPool {
}
}
fn layer_core_order(
growth_algo: LayerGrowthAlgo,
layer_idx: usize,
topo: &Topology
) -> Vec<usize> {
let mut core_order = vec![];
match growth_algo {
LayerGrowthAlgo::Sticky => {
let is_left = layer_idx % 2 == 0;
let rot_by = |layer_idx, len| -> usize {
if layer_idx <= len {
layer_idx
} else {
layer_idx % len
}
};
for i in 0..topo.cores().len() {
core_order.push(i);
}
for node in topo.nodes().iter() {
for (_, llc) in node.llcs() {
let llc_cores = llc.cores().len();
let rot = rot_by(llc_cores + (layer_idx << 1), llc_cores);
if is_left {
core_order.rotate_left(rot);
} else {
core_order.rotate_right(rot);
}
}
}
}
LayerGrowthAlgo::Linear => {
for i in 0..topo.cores().len() {
core_order.push(i);
}
}
}
core_order
}
#[derive(Debug)]
struct Layer {
name: String,
@ -1089,14 +1151,17 @@ impl Layer {
let mut cpus = bitvec![0; cpu_pool.nr_cpus];
cpus.fill(false);
let mut allowed_cpus = bitvec![0; cpu_pool.nr_cpus];
let mut layer_growth_algo = LayerGrowthAlgo::Sticky;
match &kind {
LayerKind::Confined {
cpus_range,
util_range,
nodes,
llcs,
growth_algo,
..
} => {
layer_growth_algo = growth_algo.clone();
let cpus_range = cpus_range.unwrap_or((0, std::usize::MAX));
if cpus_range.0 > cpus_range.1 || cpus_range.1 == 0 {
bail!("invalid cpus_range {:?}", cpus_range);
@ -1132,7 +1197,9 @@ impl Layer {
bail!("invalid util_range {:?}", util_range);
}
}
LayerKind::Grouped { nodes, llcs, .. } | LayerKind::Open { nodes, llcs, .. } => {
LayerKind::Grouped { growth_algo, nodes, llcs, .. } |
LayerKind::Open { growth_algo, nodes, llcs, .. } => {
layer_growth_algo = growth_algo.clone();
if nodes.len() == 0 && llcs.len() == 0 {
allowed_cpus.fill(true);
} else {
@ -1157,31 +1224,7 @@ impl Layer {
}
}
let is_left = idx % 2 == 0;
let rot_by = |idx, len| -> usize {
if idx <= len {
idx
} else {
idx % len
}
};
let mut core_order = vec![];
for i in 0..topo.cores().len() {
core_order.push(i);
}
for node in topo.nodes().iter() {
for (_, llc) in node.llcs() {
let llc_cores = llc.cores().len();
let rot = rot_by(llc_cores + (idx << 1), llc_cores);
if is_left {
core_order.rotate_left(rot);
} else {
core_order.rotate_right(rot);
}
}
}
let core_order = layer_core_order(layer_growth_algo, idx, topo);
Ok(Self {
name: name.into(),