cpu: fix core type detection via cpu_core/cpu_atom sysfs, freq-gap fallback, numeric sort
This commit is contained in:
parent
e5e15f82fb
commit
446edaab9c
1 changed files with 67 additions and 4 deletions
|
|
@ -122,10 +122,10 @@ QtObject {
|
|||
}
|
||||
}
|
||||
|
||||
// One-time: per-core max freq
|
||||
// One-time: per-core max freq (numerically sorted)
|
||||
property var _maxFreqProc: Process {
|
||||
running: true
|
||||
command: ["sh", "-c", "for f in /sys/devices/system/cpu/cpu[0-9]*/cpufreq/cpuinfo_max_freq; do [ -f \"$f\" ] && cat \"$f\" || echo 0; done 2>/dev/null"]
|
||||
command: ["sh", "-c", "ls -d /sys/devices/system/cpu/cpu[0-9]* 2>/dev/null | sort -V | while read d; do f=\"$d/cpufreq/cpuinfo_max_freq\"; [ -f \"$f\" ] && cat \"$f\" || echo 0; done"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
root.cpuCoreMaxFreq = text.trim().split("\n").filter(l => l).map(l => parseInt(l) / 1e6);
|
||||
|
|
@ -134,16 +134,79 @@ QtObject {
|
|||
}
|
||||
|
||||
// One-time: P/E-core topology
|
||||
// Priority: cpu_core/cpu_atom sysfs > topology/core_type > freq-gap heuristic
|
||||
property var _coreTypesProc: Process {
|
||||
running: true
|
||||
command: ["sh", "-c", "for d in /sys/devices/system/cpu/cpu[0-9]*/topology/core_type; do [ -f \"$d\" ] && cat \"$d\" || echo Performance; done 2>/dev/null"]
|
||||
command: ["sh", "-c", String.raw`
|
||||
# Intel hybrid: /sys/devices/cpu_core/cpus and cpu_atom/cpus give CPU ranges
|
||||
if [ -f /sys/devices/cpu_core/cpus ] && [ -f /sys/devices/cpu_atom/cpus ]; then
|
||||
core=$(cat /sys/devices/cpu_core/cpus)
|
||||
atom=$(cat /sys/devices/cpu_atom/cpus)
|
||||
echo "hybrid:$core:$atom"
|
||||
exit 0
|
||||
fi
|
||||
# Fallback: per-core topology/core_type
|
||||
ls -d /sys/devices/system/cpu/cpu[0-9]* 2>/dev/null | sort -V | while read d; do
|
||||
f="$d/topology/core_type"
|
||||
[ -f "$f" ] && cat "$f"
|
||||
done
|
||||
`]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
root.cpuCoreTypes = text.trim().split("\n").filter(l => l).map(l => l.trim());
|
||||
const out = text.trim();
|
||||
if (!out)
|
||||
return;
|
||||
if (out.startsWith("hybrid:")) {
|
||||
// Parse cpu_core/cpu_atom ranges into per-cpu type array
|
||||
const parts = out.split(":");
|
||||
const coreRange = parts[1];
|
||||
const atomRange = parts[2];
|
||||
function expandRange(s) {
|
||||
const cpus = new Set();
|
||||
for (const part of s.split(",")) {
|
||||
if (part.includes("-")) {
|
||||
const [a, b] = part.split("-").map(Number);
|
||||
for (let i = a; i <= b; i++)
|
||||
cpus.add(i);
|
||||
} else {
|
||||
cpus.add(Number(part));
|
||||
}
|
||||
}
|
||||
return cpus;
|
||||
}
|
||||
const pCores = expandRange(coreRange);
|
||||
const eCores = expandRange(atomRange);
|
||||
const maxCpu = Math.max(...pCores, ...eCores);
|
||||
const types = [];
|
||||
for (let i = 0; i <= maxCpu; i++)
|
||||
types.push(eCores.has(i) ? "Efficiency" : "Performance");
|
||||
root.cpuCoreTypes = types;
|
||||
} else {
|
||||
// topology/core_type output
|
||||
const types = out.split("\n").filter(l => l).map(l => l.trim());
|
||||
if (types.length > 0)
|
||||
root.cpuCoreTypes = types;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: infer P/E from max freq gap when no sysfs topology is available
|
||||
function _inferCoreTypesFromFreq() {
|
||||
if (cpuCoreTypes.length > 0 || cpuCoreMaxFreq.length < 2)
|
||||
return;
|
||||
const freqs = cpuCoreMaxFreq.filter(f => f > 0);
|
||||
if (!freqs.length)
|
||||
return;
|
||||
const maxF = Math.max(...freqs);
|
||||
const minF = Math.min(...freqs);
|
||||
if (maxF > 0 && minF > 0 && (maxF - minF) / maxF > 0.15) {
|
||||
const threshold = (maxF + minF) / 2;
|
||||
cpuCoreTypes = cpuCoreMaxFreq.map(f => f >= threshold ? "Performance" : "Efficiency");
|
||||
}
|
||||
}
|
||||
onCpuCoreMaxFreqChanged: Qt.callLater(_inferCoreTypesFromFreq)
|
||||
|
||||
// Disk via df
|
||||
property var _diskProc: Process {
|
||||
id: diskProc
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue