Fix SMT behaviour paper cuts

This commit is contained in:
NGnius (Graham) 2023-01-05 21:16:37 -05:00
parent 13bf31611d
commit fbb68e0d51
3 changed files with 41 additions and 19 deletions

View file

@ -60,6 +60,8 @@ pub enum CpuMessage {
impl CpuMessage {
fn process(self, settings: &mut dyn TCpus) {
// NOTE: "cpu" refers to the Linux kernel definition of a CPU, which is actually a hardware thread
// not to be confused with a CPU chip, which usually has multiple hardware threads (cpu cores/threads) in the chip
match self {
Self::SetCpuOnline(index, status) => {settings.cpus().get_mut(index).map(|c| *c.online() = status);},
Self::SetCpusOnline(cpus) => {
@ -68,10 +70,38 @@ impl CpuMessage {
}
},
Self::SetSmt(status, cb) => {
*settings.smt() = status;
if *settings.smt() == status {
// already set, do nothing
} else if status {
// set SMT on
*settings.smt() = true;
let mut should_be_online = false;
let cpu_count = settings.len();
for i in (0..cpu_count).rev() {
if *settings.cpus()[i].online() && !should_be_online {
should_be_online = true;
// enable the odd-numbered thread right before
// for 1c:2t configs (i.e. anything with SMT2), the highest cpu core is always odd
// (e.g. 4c8t has CPUs 0-7, inclusive)
// this enables the """fake""" (i.e. odd) cpu which is disabled when SMT is set off
if i % 2 == 0 && i+1 != cpu_count {
*(settings.cpus()[i+1].online()) = true;
}
} else {
*settings.cpus()[i].online() = should_be_online;
}
}
} else {
// set SMT off
*settings.smt() = false;
for i in 0..settings.len() {
// this disables the """fake""" (odd) cpu for appearances' sake
// the kernel will automatically disable that same cpu when SMT is changed
*settings.cpus()[i].online() = *settings.cpus()[i].online() && (status || i % 2 == 0);
}
}
let mut result = Vec::with_capacity(settings.len());
for i in 0..settings.len() {
*settings.cpus()[i].online() = *settings.cpus()[i].online() && (status || i % 2 == 0);
result.push(*settings.cpus()[i].online());
}
cb(result);

View file

@ -120,8 +120,8 @@ export async function unsetBatteryChargeMode(): Promise<any[]> {
// CPU
export async function setCpuSmt(status: boolean): Promise<boolean> {
return (await call_backend("CPU_set_smt", [status]))[0];
export async function setCpuSmt(status: boolean): Promise<boolean[]> {
return await call_backend("CPU_set_smt", [status]);
}
/*export async function getCpuCount(): Promise<number> {

View file

@ -251,18 +251,10 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
description="Enables odd-numbered CPUs"
onChange={(smt: boolean) => {
backend.log(backend.LogLevel.Debug, "SMT is now " + smt.toString());
const cpus = get_value(ONLINE_CPUS);
//const cpus = get_value(ONLINE_CPUS);
const smtNow = smt && smtAllowed;
backend.resolve(backend.setCpuSmt(smtNow), (newVal: boolean) => {
set_value(SMT_CPU, newVal);
});
let onlines: boolean[] = [];
for (let i = 0; i < total_cpus; i++) {
const online = (smtNow? i < cpus : (i % 2 == 0) && (i < cpus * 2))
|| (!smtNow && cpus == 4);
onlines.push(online);
}
backend.resolve(backend.setCpuOnlines(onlines), (statii: boolean[]) => {
backend.resolve(backend.setCpuSmt(smtNow), (statii: boolean[]) => {
set_value(SMT_CPU, smtNow);
set_value(ONLINE_STATUS_CPUS, statii);
const count = countCpus(statii);
set_value(ONLINE_CPUS, count);
@ -276,7 +268,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
label="Threads"
value={get_value(ONLINE_CPUS)}
step={1}
max={get_value(SMT_CPU) || !smtAllowed ? total_cpus : total_cpus/2}
max={(get_value(SMT_CPU) || !smtAllowed) ? total_cpus : total_cpus/2}
min={1}
showValue={true}
onChange={(cpus: number) => {
@ -411,9 +403,9 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
description="Allow the CPU thread to do work"
onChange={(status: boolean) => {
backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString());
if (get_value(SMT_CPU)) {
backend.resolve(backend.setCpuSmt(false), (newVal: boolean) => {
set_value(SMT_CPU, newVal);
if (!get_value(SMT_CPU)) {
backend.resolve(backend.setCpuSmt(true), (_newVal: boolean[]) => {
set_value(SMT_CPU, true);
});
}
backend.resolve(backend.setCpuOnline(advancedCpuIndex, status), (newVal: boolean) => {