From cc87d771a2ed9ec563475744517ed7b7402b07ef Mon Sep 17 00:00:00 2001 From: Sola Date: Mon, 23 Mar 2026 21:35:25 +0800 Subject: [PATCH] fix: correctly map amd zen cpu core temps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On AMD multi-CCD CPUs (e.g. Ryzen 5950X), btop++ incorrectly maps per-CCD temperature sensors to CPU cores. `Tccd1` is shown for even-numbered cores (0, 2, 4, 6, ...) and `Tccd2` for odd-numbered cores (1, 3, 5, 7, ...), when the correct mapping is `Tccd1` → cores 0–7 (and their SMT siblings 16–23) and `Tccd2` → cores 8–15 (and their SMT siblings 24–31). --- src/linux/btop_collect.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index 1d52a44..edafde4 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -710,12 +710,15 @@ namespace Cpu { std::unordered_map core_map; if (cpu_temp_only) return core_map; + const int num_sensors = core_sensors.size(); + //? Try to get core mapping from /proc/cpuinfo ifstream cpuinfo(Shared::procPath / "cpuinfo"); if (cpuinfo.good()) { int cpu{}; int core{}; - int n{}; + int max_core{}; + std::unordered_map cpu_to_core; for (string instr; cpuinfo >> instr;) { if (instr == "processor") { cpuinfo.ignore(SSmax, ':'); @@ -724,30 +727,30 @@ namespace Cpu { else if (instr.starts_with("core")) { cpuinfo.ignore(SSmax, ':'); cpuinfo >> core; - if (std::cmp_greater_equal(core, core_sensors.size())) { - if (std::cmp_greater_equal(n, core_sensors.size())) n = 0; - core_map[cpu] = n++; - } - else - core_map[cpu] = core; + cpu_to_core[cpu] = core; + max_core = std::max(max_core, core); } cpuinfo.ignore(SSmax, '\n'); } + if (not cpu_to_core.empty()) + //? Divide core ID space evenly across sensors (handles AMD multi-CCD, e.g. 5950x: IDs 0-7 -> Tccd1, 8-15 -> Tccd2) + for (const auto& [cpu_id, core_id] : cpu_to_core) { + core_map[cpu_id] = core_id * num_sensors / (max_core + 1); + } } //? If core mapping from cpuinfo was incomplete try to guess remainder, if missing completely, map 0-0 1-1 2-2 etc. if (cmp_less(core_map.size(), Shared::coreCount)) { if (Shared::coreCount % 2 == 0 and (long)core_map.size() == Shared::coreCount / 2) { - for (int i = 0, n = 0; i < Shared::coreCount / 2; i++) { - if (std::cmp_greater_equal(n, core_sensors.size())) n = 0; - core_map[Shared::coreCount / 2 + i] = n++; + //? SMT siblings mirror their first half of cores. + for (int i = 0; i < Shared::coreCount / 2; i++) { + core_map[Shared::coreCount / 2 + i] = core_map.count(i) ? core_map.at(i) : (i % num_sensors); } } else { core_map.clear(); - for (int i = 0, n = 0; i < Shared::coreCount; i++) { - if (std::cmp_greater_equal(n, core_sensors.size())) n = 0; - core_map[i] = n++; + for (int i = 0; i < Shared::coreCount; i++) { + core_map[i] = (i * num_sensors) / Shared::coreCount; } } } @@ -761,7 +764,7 @@ namespace Cpu { if (vals.size() != 2) continue; int change_id = std::stoi(vals.at(0)); int new_id = std::stoi(vals.at(1)); - if (not core_map.contains(change_id) or cmp_greater(new_id, core_sensors.size())) continue; + if (not core_map.contains(change_id) or cmp_greater(new_id, num_sensors)) continue; core_map.at(change_id) = new_id; } }