@@ -40,6 +40,7 @@ struct hwloc_x86_backend_data_s {
40
40
char * src_cpuiddump_path ;
41
41
int is_knl ;
42
42
int is_hybrid ;
43
+ int has_power_efficiency_ranking ;
43
44
int found_die_ids ;
44
45
int found_complex_ids ;
45
46
int found_unit_ids ;
@@ -232,6 +233,7 @@ struct procinfo {
232
233
233
234
unsigned hybridcoretype ;
234
235
unsigned hybridnativemodel ;
236
+ unsigned power_efficiency_ranking ;
235
237
};
236
238
237
239
enum cpuid_type {
@@ -586,6 +588,32 @@ static void read_extended_topo(struct hwloc_x86_backend_data_s *data, struct pro
586
588
switch (apic_type ) {
587
589
case 1 :
588
590
threadid = id ;
591
+ if (leaf == 0x80000026 ) {
592
+ /* AMD 0x80000026 also reports more info about cores.
593
+ * bit eax[31] = "AsymmetricCores" = set if cores are asymmetric (different numbers of threads per core)
594
+ * => doesn't seem needed in hwloc.
595
+ */
596
+
597
+ if (eax & 0x40000000 ) {
598
+ /* HeterogeneousCoreTopology:
599
+ * When set, not all instances at the current hierarchy
600
+ * level have the same Core Type topology
601
+ */
602
+ data -> is_hybrid = 1 ;
603
+ }
604
+
605
+ if (eax & 0x20000000 ) {
606
+ /* EfficiencyRankingAvailable */
607
+ data -> has_power_efficiency_ranking = 1 ;
608
+ /* "a core with a lower value has intrinsically better power,
609
+ * but potentially lower performance potential vs cores with a higher value."
610
+ */
611
+ infos -> power_efficiency_ranking = (ebx >> 16 ) & 0xff ;
612
+ }
613
+
614
+ infos -> hybridcoretype = (ebx >> 28 ) & 0xf ; /* 0 = P, 1 = E */
615
+ infos -> hybridnativemodel = (ebx >> 24 ) & 0xf ; /* 0 = Zen4 */
616
+ }
589
617
break ;
590
618
case 2 :
591
619
infos -> ids [CORE ] = id ;
@@ -1413,10 +1441,8 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long
1413
1441
if (data -> apicid_unique ) {
1414
1442
summarize (backend , infos , flags );
1415
1443
1416
- if (data -> is_hybrid
1417
- && !(topology -> flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS )) {
1418
- /* use hybrid info for cpukinds */
1419
- if (cpuid_type == intel ) {
1444
+ if (!(topology -> flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS )) {
1445
+ if (data -> is_hybrid && cpuid_type == intel ) {
1420
1446
/* Hybrid Intel */
1421
1447
hwloc_bitmap_t atomset = hwloc_bitmap_alloc ();
1422
1448
hwloc_bitmap_t coreset = hwloc_bitmap_alloc ();
@@ -1454,6 +1480,75 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long
1454
1480
} else {
1455
1481
hwloc_bitmap_free (coreset );
1456
1482
}
1483
+
1484
+ } else if (data -> is_hybrid && cpuid_type == amd ) {
1485
+ /* Hybrid AMD */
1486
+ hwloc_bitmap_t Pset = hwloc_bitmap_alloc ();
1487
+ hwloc_bitmap_t Eset = hwloc_bitmap_alloc ();
1488
+ for (i = 0 ; i < nbprocs ; i ++ ) {
1489
+ if (infos [i ].hybridcoretype == 0x0 )
1490
+ hwloc_bitmap_set (Pset , i );
1491
+ else if (infos [i ].hybridcoretype == 0x1 )
1492
+ hwloc_bitmap_set (Eset , i );
1493
+ }
1494
+ /* register AMD-ECore set if any */
1495
+ if (!hwloc_bitmap_iszero (Eset )) {
1496
+ struct hwloc_infos_s _infos ;
1497
+ struct hwloc_info_s infoattr ;
1498
+ infoattr .name = (char * ) "CoreType" ;
1499
+ infoattr .value = (char * ) "AMD-ECore" ;
1500
+ _infos .array = & infoattr ;
1501
+ _infos .count = 1 ;
1502
+ _infos .allocated = 0 ;
1503
+ hwloc_internal_cpukinds_register (topology , Eset , HWLOC_CPUKIND_EFFICIENCY_UNKNOWN , & _infos , 0 );
1504
+ /* the cpuset is given to the callee */
1505
+ } else {
1506
+ hwloc_bitmap_free (Eset );
1507
+ }
1508
+ /* register AMD-PCore set if any */
1509
+ if (!hwloc_bitmap_iszero (Pset )) {
1510
+ struct hwloc_infos_s _infos ;
1511
+ struct hwloc_info_s infoattr ;
1512
+ infoattr .name = (char * ) "CoreType" ;
1513
+ infoattr .value = (char * ) "AMD-PCore" ;
1514
+ _infos .array = & infoattr ;
1515
+ _infos .count = 1 ;
1516
+ _infos .allocated = 0 ;
1517
+ hwloc_internal_cpukinds_register (topology , Pset , HWLOC_CPUKIND_EFFICIENCY_UNKNOWN , & _infos , 0 );
1518
+ /* the cpuset is given to the callee */
1519
+ } else {
1520
+ hwloc_bitmap_free (Pset );
1521
+ }
1522
+ }
1523
+
1524
+ if (data -> has_power_efficiency_ranking && cpuid_type == amd ) {
1525
+ /* AMD Power Efficiency Ranking */
1526
+ hwloc_bitmap_t rankings = hwloc_bitmap_alloc ();
1527
+ if (!rankings ) {
1528
+ fprintf (stderr , "[hwloc/x86/cpukinds] failed to allocated rankings bitmap.\n" );
1529
+ } else {
1530
+ /* list existing rankings */
1531
+ for (i = 0 ; i < nbprocs ; i ++ )
1532
+ hwloc_bitmap_set (rankings , infos [i ].power_efficiency_ranking );
1533
+ if (hwloc_bitmap_weight (rankings ) > 1 ) {
1534
+ while (!hwloc_bitmap_iszero (rankings )) {
1535
+ unsigned ranking = hwloc_bitmap_first (rankings );
1536
+ hwloc_bitmap_t rankset = hwloc_bitmap_alloc ();
1537
+ if (!rankset ) {
1538
+ fprintf (stderr , "[hwloc/x86/cpukinds] failed to allocated rankset bitmap.\n" );
1539
+ break ;
1540
+ } else {
1541
+ for (i = 0 ; i < nbprocs ; i ++ )
1542
+ if (infos [i ].power_efficiency_ranking == (unsigned ) ranking )
1543
+ hwloc_bitmap_set (rankset , i );
1544
+ hwloc_internal_cpukinds_register (topology , rankset , ranking , NULL , 0 );
1545
+ /* the cpuset is given to the callee */
1546
+ }
1547
+ hwloc_bitmap_clr (rankings , ranking );
1548
+ }
1549
+ }
1550
+ hwloc_bitmap_free (rankings );
1551
+ }
1457
1552
}
1458
1553
}
1459
1554
} else {
@@ -1896,6 +1991,7 @@ hwloc_x86_component_instantiate(struct hwloc_topology *topology,
1896
1991
data = HWLOC_BACKEND_PRIVATE_DATA (backend );
1897
1992
data -> is_knl = 0 ;
1898
1993
data -> is_hybrid = 0 ;
1994
+ data -> has_power_efficiency_ranking = 0 ;
1899
1995
data -> apicid_set = hwloc_bitmap_alloc ();
1900
1996
data -> apicid_unique = 1 ;
1901
1997
data -> src_cpuiddump_path = NULL ;
0 commit comments