MINOR: cpu-topo: boost the capacity of performance cores with cpufreq

Cpufreq alone isn't a good metric on heterogenous CPUs because efficient
cores can reach almost as high frequencies as performant ones. Tests have
shown that majoring performance cores by 50% gives a pretty accurate
estimate of the performance to expect on modern CPUs, and that counting
+33% per extra SMT thread is reasonable as well. We don't have the info
about the core's quality, but using the presence of SMT is a reasonable
approach in this case, given that efficiency cores will not use it.

As an example, using one thread of each of the 8 P-cores of an intel
i9-14900k gives 395k rps for a corrected total capacity of 69.3k, using
the 16 E-cores gives 40.5k for a total capacity of 70.4k, and using both
threads of 6 P-cores gives 41.1k for a total capacity of 69.6k. Thus the
3 same scores deliver the same performance in various combinations.
This commit is contained in:
Willy Tarreau 2025-03-14 17:06:00 +01:00
parent e4aa13e786
commit c5ddf4a5b2

View file

@ -419,13 +419,20 @@ int cpu_detect_topology(void)
* start just due to this. Thus we start with cpufreq and fall
* back to acpi_cppc. If it becomes an issue, we could imagine
* forcing the value to all members of the same core and even
* cluster.
* cluster. Since the frequency alone is not a good criterion
* to qualify the CPU quality (perf vs efficiency core), instead
* we rely on the thread count to gauge if it's a performant or
* an efficient core, and we major performant cores' capacity
* by 50% (shown to be roughly correct on modern CPUs).
*/
if (ha_cpu_topo[cpu].capa < 0 &&
read_line_to_trash(NUMA_DETECT_SYSTEM_SYSFS_PATH "/cpu/cpu%d/cpufreq/scaling_max_freq", cpu) >= 0) {
/* This is in kHz, turn it to MHz to stay below 32k */
if (trash.data)
if (trash.data) {
ha_cpu_topo[cpu].capa = (str2uic(trash.area) + 999U) / 1000U;
if (ha_cpu_topo[cpu].th_cnt > 1)
ha_cpu_topo[cpu].capa = ha_cpu_topo[cpu].capa * 3 / 2;
}
}
if (ha_cpu_topo[cpu].capa < 0 &&