From 68df56896938a62b4abfc19abacc5b2be1f9dcef Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 11 May 2023 16:33:38 +0200 Subject: [PATCH 1/2] x86: build cpukinds from AMD CPUID leaf 0x80000026 Use coretype to build "AMD-ECore" and "AMD-Pcore" kinds. Use power efficiency rankings to build kinds with native efficiencies. Signed-off-by: Brice Goglin --- hwloc/topology-x86.c | 104 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 4 deletions(-) diff --git a/hwloc/topology-x86.c b/hwloc/topology-x86.c index 55e1fcfab..42808eff4 100644 --- a/hwloc/topology-x86.c +++ b/hwloc/topology-x86.c @@ -40,6 +40,7 @@ struct hwloc_x86_backend_data_s { char *src_cpuiddump_path; int is_knl; int is_hybrid; + int has_power_efficiency_ranking; int found_die_ids; int found_complex_ids; int found_unit_ids; @@ -232,6 +233,7 @@ struct procinfo { unsigned hybridcoretype; unsigned hybridnativemodel; + unsigned power_efficiency_ranking; }; enum cpuid_type { @@ -586,6 +588,32 @@ static void read_extended_topo(struct hwloc_x86_backend_data_s *data, struct pro switch (apic_type) { case 1: threadid = id; + if (leaf == 0x80000026) { + /* AMD 0x80000026 also reports more info about cores. + * bit eax[31] = "AsymmetricCores" = set if cores are asymmetric (different numbers of threads per core) + * => doesn't seem needed in hwloc. + */ + + if (eax & 0x40000000) { + /* HeterogeneousCoreTopology: + * When set, not all instances at the current hierarchy + * level have the same Core Type topology + */ + data->is_hybrid = 1; + } + + if (eax & 0x20000000) { + /* EfficiencyRankingAvailable */ + data->has_power_efficiency_ranking = 1; + /* "a core with a lower value has intrinsically better power, + * but potentially lower performance potential vs cores with a higher value." + */ + infos->power_efficiency_ranking = (ebx >> 16) & 0xff; + } + + infos->hybridcoretype = (ebx >> 28) & 0xf; /* 0 = P, 1 = E */ + infos->hybridnativemodel = (ebx >> 24) & 0xf; /* 0 = Zen4 */ + } break; case 2: infos->ids[CORE] = id; @@ -1413,10 +1441,8 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long if (data->apicid_unique) { summarize(backend, infos, flags); - if (data->is_hybrid - && !(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS)) { - /* use hybrid info for cpukinds */ - if (cpuid_type == intel) { + if (!(topology->flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS)) { + if (data->is_hybrid && cpuid_type == intel) { /* Hybrid Intel */ hwloc_bitmap_t atomset = hwloc_bitmap_alloc(); hwloc_bitmap_t coreset = hwloc_bitmap_alloc(); @@ -1454,6 +1480,75 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long } else { hwloc_bitmap_free(coreset); } + + } else if (data->is_hybrid && cpuid_type == amd) { + /* Hybrid AMD */ + hwloc_bitmap_t Pset = hwloc_bitmap_alloc(); + hwloc_bitmap_t Eset = hwloc_bitmap_alloc(); + for(i=0; ihas_power_efficiency_ranking && cpuid_type == amd) { + /* AMD Power Efficiency Ranking */ + hwloc_bitmap_t rankings = hwloc_bitmap_alloc(); + if (!rankings) { + fprintf(stderr, "[hwloc/x86/cpukinds] failed to allocated rankings bitmap.\n"); + } else { + /* list existing rankings */ + for(i=0; i 1) { + while (!hwloc_bitmap_iszero(rankings)) { + unsigned ranking = hwloc_bitmap_first(rankings); + hwloc_bitmap_t rankset = hwloc_bitmap_alloc(); + if (!rankset) { + fprintf(stderr, "[hwloc/x86/cpukinds] failed to allocated rankset bitmap.\n"); + break; + } else { + for(i=0; iis_knl = 0; data->is_hybrid = 0; + data->has_power_efficiency_ranking = 0; data->apicid_set = hwloc_bitmap_alloc(); data->apicid_unique = 1; data->src_cpuiddump_path = NULL; From 2229659ac7f589adc4d13101e1561ca4c4fd17dd Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 22 Aug 2024 15:03:00 +0200 Subject: [PATCH 2/2] WIP debug AMD CPUID cpukinds PPR says it's in core level, which means we get the info from each thread? Signed-off-by: Brice Goglin --- hwloc/topology-x86.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hwloc/topology-x86.c b/hwloc/topology-x86.c index 42808eff4..78837862a 100644 --- a/hwloc/topology-x86.c +++ b/hwloc/topology-x86.c @@ -585,6 +585,15 @@ static void read_extended_topo(struct hwloc_x86_backend_data_s *data, struct pro id); infos->apicid = apic_id; infos->otherids[level] = UINT_MAX; +if (leaf == 0x80000026 && apic_id == 0) { + printf("HybridCPU info at level %u\n", apic_type); + printf(" AsymmetricCores = %u\n", (eax & 0x80000000)>>31); + printf(" HeteroCoreTyopology = %u\n", (eax & 0x40000000)>>30); + printf(" EffRankingAvailable = %u\n", (eax & 0x20000000)>>29); + printf(" CoreType = %u\n", (ebx >> 28) & 0xf); + printf(" Model = %u\n", (ebx >> 24) & 0xf); + printf(" EffRanking = %u\n", (ebx >> 16) & 0xff); +} switch (apic_type) { case 1: threadid = id;