Created
October 6, 2024 21:18
-
-
Save azenla/c4a16f256845d169298115d938d8fedc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Clone, Copy, Debug)] | |
pub enum CpuClass { | |
Standard, | |
Performance, | |
Efficiency, | |
} | |
#[derive(Clone, Copy, Debug)] | |
pub struct CpuTopologyInfo { | |
pub core: u32, | |
pub socket: u32, | |
pub node: u32, | |
pub thread: u32, | |
pub class: CpuClass, | |
} | |
fn labeled_topology(input: &[SysctlCputopo]) -> Vec<CpuTopologyInfo> { | |
let mut cores: IndexMap<(u32, u32, u32), Vec<CpuTopologyInfo>> = IndexMap::new(); | |
let mut pe_cores = false; | |
let mut last: Option<SysctlCputopo> = None; | |
for item in input { | |
if cores.is_empty() { | |
cores.insert( | |
(item.core, item.socket, item.node), | |
vec![CpuTopologyInfo { | |
core: item.core, | |
socket: item.socket, | |
thread: 0, | |
node: item.node, | |
class: CpuClass::Standard, | |
}], | |
); | |
last = Some(*item); | |
continue; | |
} | |
if last | |
.map(|last| { | |
item.core | |
.checked_sub(last.core) | |
.map(|diff| diff >= 3) | |
.unwrap_or(false) | |
}) | |
.unwrap_or(false) | |
{ | |
// detect if performance cores seem to be kicking in. | |
if let Some(last) = last { | |
if let Some(list) = cores.get_mut(&(last.core, last.socket, last.node)) { | |
for other in list { | |
other.class = CpuClass::Performance; | |
} | |
} | |
} | |
let list = cores | |
.entry((item.core, item.socket, item.node)) | |
.or_default(); | |
for old in &mut *list { | |
old.class = CpuClass::Performance; | |
} | |
list.push(CpuTopologyInfo { | |
core: item.core, | |
socket: item.socket, | |
thread: 0, | |
node: item.node, | |
class: CpuClass::Performance, | |
}); | |
pe_cores = true; | |
} else if pe_cores && last.map(|last| item.core == last.core + 1).unwrap_or(false) { | |
// detect efficiency cores if P/E cores are in use. | |
if let Some(last) = last { | |
if let Some(list) = cores.get_mut(&(last.core, last.socket, last.node)) { | |
for other in list { | |
other.class = CpuClass::Efficiency; | |
} | |
} | |
} | |
let list = cores | |
.entry((item.core, item.socket, item.node)) | |
.or_default(); | |
list.push(CpuTopologyInfo { | |
core: item.core, | |
socket: item.socket, | |
thread: 0, | |
node: item.node, | |
class: CpuClass::Efficiency, | |
}); | |
} else { | |
let list = cores | |
.entry((item.core, item.socket, item.node)) | |
.or_default(); | |
if list.is_empty() { | |
list.push(CpuTopologyInfo { | |
core: item.core, | |
socket: item.socket, | |
thread: 0, | |
node: item.node, | |
class: CpuClass::Standard, | |
}); | |
} else { | |
list.push(CpuTopologyInfo { | |
core: item.core, | |
socket: item.socket, | |
thread: 0, | |
node: item.node, | |
class: list | |
.first() | |
.map(|first| first.class) | |
.unwrap_or(CpuClass::Standard), | |
}); | |
} | |
} | |
last = Some(*item); | |
} | |
for threads in cores.values_mut() { | |
for (index, thread) in threads.iter_mut().enumerate() { | |
thread.thread = index as u32; | |
} | |
} | |
cores.into_values().flatten().collect::<Vec<_>>() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment