diff --git a/linux/LinuxMachine.c b/linux/LinuxMachine.c index c246e9f22..1a941c497 100644 --- a/linux/LinuxMachine.c +++ b/linux/LinuxMachine.c @@ -731,6 +731,26 @@ static void LinuxMachine_computeThreadIndices(LinuxMachine* this) { } cpus[i].threadIndex = threadIndex; } + + /* Now compute a normalized physical core index for each CPU. + On many systems, this index will match the following: + physicalID*(maxPhysicalID+1)+coreID + But there are some systems where this is not true, either + because CoreIDs are not contiguous or because cpus are + enumerated in an alternative order, or both. */ + for (size_t i = 1; i <= super->existingCPUs; i++) { + cpus[i].coreIndex = 0; + for (size_t j = i - 1; j >= 1; j--) { + if (cpus[i].threadIndex == cpus[j].threadIndex) { + cpus[i].coreIndex = cpus[j].coreIndex + 1; + break; + } + } + } + + /* Set core & thread indices to zero for cpu0 (average) */ + cpus[0].coreIndex = 0; + cpus[0].threadIndex = 0; } static void LinuxMachine_scanCPUFrequency(LinuxMachine* this) { @@ -850,9 +870,7 @@ int Machine_getCPUPhysicalCoreID(const Machine* super, unsigned int id) { const LinuxMachine* this = (const LinuxMachine*) super; assert(id < super->existingCPUs); - - const CPUData* cpu = &this->cpuData[id + 1]; - return cpu->physicalID * (this->maxCoreID + 1) + cpu->coreID; + return this->cpuData[id + 1].coreIndex; } int Machine_getCPUThreadIndex(const Machine* super, unsigned int id) { diff --git a/linux/LinuxMachine.h b/linux/LinuxMachine.h index 3f6e670c1..efcf8f86f 100644 --- a/linux/LinuxMachine.h +++ b/linux/LinuxMachine.h @@ -54,6 +54,7 @@ typedef struct CPUData_ { int physicalID; /* different for each CPU socket */ int coreID; /* same for hyperthreading */ int ccdID; /* same for each AMD chiplet */ + int coreIndex; /* Normalized physical core ID */ int threadIndex; /* SMT thread index: 0 for first thread, 1 for second, etc. */ bool online;