@@ -39,6 +39,7 @@ struct hwloc_x86_backend_data_s {
39
39
char * src_cpuiddump_path ;
40
40
int is_knl ;
41
41
int is_hybrid ;
42
+ int has_power_efficiency_ranking ;
42
43
int found_die_ids ;
43
44
int found_complex_ids ;
44
45
int found_unit_ids ;
@@ -231,6 +232,7 @@ struct procinfo {
231
232
232
233
unsigned hybridcoretype ;
233
234
unsigned hybridnativemodel ;
235
+ unsigned power_efficiency_ranking ;
234
236
};
235
237
236
238
enum cpuid_type {
@@ -581,6 +583,32 @@ static void read_extended_topo(struct hwloc_x86_backend_data_s *data, struct pro
581
583
switch (apic_type ) {
582
584
case 1 :
583
585
threadid = id ;
586
+ if (leaf == 0x80000026 ) {
587
+ /* AMD 0x80000026 also reports more info about cores.
588
+ * bit eax[31] = "AsymmetricCores" = set if cores are asymmetric (different numbers of threads per core)
589
+ * => doesn't seem needed in hwloc.
590
+ */
591
+
592
+ if (eax & 0x40000000 ) {
593
+ /* HeterogeneousCoreTopology:
594
+ * When set, not all instances at the current hierarchy
595
+ * level have the same Core Type topology
596
+ */
597
+ data -> is_hybrid = 1 ;
598
+ }
599
+
600
+ if (eax & 0x20000000 ) {
601
+ /* EfficiencyRankingAvailable */
602
+ data -> has_power_efficiency_ranking = 1 ;
603
+ /* "a core with a lower value has intrinsically better power,
604
+ * but potentially lower performance potential vs cores with a higher value."
605
+ */
606
+ infos -> power_efficiency_ranking = (ebx >> 16 & 0xff );
607
+ }
608
+
609
+ infos -> hybridcoretype = (ebx >> 28 ) & 0xf ; /* 0 = P, 1 = E */
610
+ infos -> hybridnativemodel = (ebx >> 24 ) & 0xf ; /* 0 = Zen4 */
611
+ }
584
612
break ;
585
613
case 2 :
586
614
infos -> ids [CORE ] = id ;
@@ -1405,10 +1433,8 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long
1405
1433
if (data -> apicid_unique ) {
1406
1434
summarize (backend , infos , flags );
1407
1435
1408
- if (data -> is_hybrid
1409
- && !(topology -> flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS )) {
1410
- /* use hybrid info for cpukinds */
1411
- if (cpuid_type == intel ) {
1436
+ if (!(topology -> flags & HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS )) {
1437
+ if (data -> is_hybrid && cpuid_type == intel ) {
1412
1438
/* Hybrid Intel */
1413
1439
hwloc_bitmap_t atomset = hwloc_bitmap_alloc ();
1414
1440
hwloc_bitmap_t coreset = hwloc_bitmap_alloc ();
@@ -1438,9 +1464,71 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long
1438
1464
} else {
1439
1465
hwloc_bitmap_free (coreset );
1440
1466
}
1467
+
1468
+ } else if (data -> is_hybrid && cpuid_type == amd ) {
1469
+ /* Hybrid AMD */
1470
+ hwloc_bitmap_t Pset = hwloc_bitmap_alloc ();
1471
+ hwloc_bitmap_t Eset = hwloc_bitmap_alloc ();
1472
+ for (i = 0 ; i < nbprocs ; i ++ ) {
1473
+ if (infos [i ].hybridcoretype == 0x0 )
1474
+ hwloc_bitmap_set (Pset , i );
1475
+ else if (infos [i ].hybridcoretype == 0x1 )
1476
+ hwloc_bitmap_set (Eset , i );
1477
+ }
1478
+ /* register AMD-ECore set if any */
1479
+ if (!hwloc_bitmap_iszero (Eset )) {
1480
+ struct hwloc_info_s infoattr ;
1481
+ infoattr .name = (char * ) "CoreType" ;
1482
+ infoattr .value = (char * ) "AMD-ECore" ;
1483
+ hwloc_internal_cpukinds_register (topology , Eset , HWLOC_CPUKIND_EFFICIENCY_UNKNOWN , & infoattr , 1 , 0 );
1484
+ /* the cpuset is given to the callee */
1485
+ } else {
1486
+ hwloc_bitmap_free (Eset );
1487
+ }
1488
+ /* register AMD-PCore set if any */
1489
+ if (!hwloc_bitmap_iszero (Pset )) {
1490
+ struct hwloc_info_s infoattr ;
1491
+ infoattr .name = (char * ) "CoreType" ;
1492
+ infoattr .value = (char * ) "AMD-PCore" ;
1493
+ hwloc_internal_cpukinds_register (topology , Pset , HWLOC_CPUKIND_EFFICIENCY_UNKNOWN , & infoattr , 1 , 0 );
1494
+ /* the cpuset is given to the callee */
1495
+ } else {
1496
+ hwloc_bitmap_free (Pset );
1497
+ }
1498
+ }
1499
+
1500
+ if (data -> has_power_efficiency_ranking && cpuid_type == amd ) {
1501
+ /* AMD Power Efficiency Ranking */
1502
+ hwloc_bitmap_t rankings = hwloc_bitmap_alloc ();
1503
+ if (!rankings ) {
1504
+ fprintf (stderr , "[hwloc/x86/cpukinds] failed to allocated rankings bitmap.\n" );
1505
+ } else {
1506
+ /* list existing rankings */
1507
+ for (i = 0 ; i < nbprocs ; i ++ )
1508
+ hwloc_bitmap_set (rankings , infos [i ].power_efficiency_ranking );
1509
+ if (hwloc_bitmap_weight (rankings ) > 1 ) {
1510
+ while (!hwloc_bitmap_iszero (rankings )) {
1511
+ unsigned ranking = hwloc_bitmap_first (rankings );
1512
+ hwloc_bitmap_t rankset = hwloc_bitmap_alloc ();
1513
+ if (!rankset ) {
1514
+ fprintf (stderr , "[hwloc/x86/cpukinds] failed to allocated rankset bitmap.\n" );
1515
+ break ;
1516
+ } else {
1517
+ for (i = 0 ; i < nbprocs ; i ++ )
1518
+ if (infos [i ].power_efficiency_ranking == (unsigned ) ranking )
1519
+ hwloc_bitmap_set (rankset , i );
1520
+ hwloc_internal_cpukinds_register (topology , rankset , ranking , NULL , 0 , 0 );
1521
+ /* the cpuset is given to the callee */
1522
+ }
1523
+ hwloc_bitmap_clr (rankings , ranking );
1524
+ }
1525
+ }
1526
+ hwloc_bitmap_free (rankings );
1527
+ }
1441
1528
}
1442
1529
}
1443
1530
}
1531
+
1444
1532
/* if !data->apicid_unique, do nothing and return success, so that the caller does nothing either */
1445
1533
1446
1534
return 0 ;
@@ -1886,6 +1974,7 @@ hwloc_x86_component_instantiate(struct hwloc_topology *topology,
1886
1974
/* default values */
1887
1975
data -> is_knl = 0 ;
1888
1976
data -> is_hybrid = 0 ;
1977
+ data -> has_power_efficiency_ranking = 0 ;
1889
1978
data -> apicid_set = hwloc_bitmap_alloc ();
1890
1979
data -> apicid_unique = 1 ;
1891
1980
data -> src_cpuiddump_path = NULL ;
0 commit comments