Tools/ftscalingbench picks too few CPUs on processors with unevenly clocked performance cores
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Tools/ftscalingbench chooses which CPUs to run its worker threads on by reading lscpu -p=cpu,node,core,MAXMHZ and keeping one CPU per physical core, skipping efficiency cores. The filter for that last part is an exact comparison against the highest clock on the machine:
max_mhz_all = max(row[3] for row in table)
for cpu, node, core, maxmhz in table:
if node == 0 and core not in cores and maxmhz == max_mhz_all:
That works when every performance core shares one clock ceiling. It does not hold on parts with Intel Turbo Boost Max 3.0, which bins a couple of favoured cores above their siblings. Only those few then pass the filter, and the rest of the performance cores are dropped along with the efficiency cores.
On an i7-14650HX (8 performance cores, two of them rated 5200 MHz and the other six 5000 MHz, plus 8 efficiency cores at 3700 MHz) the selection returns [8, 10] and the benchmark prints:
Running benchmarks with 2 threads
It then reports scaling figures for 2 threads on a machine with 8 performance cores, without any indication that it picked a smaller thread count than the hardware offers. The numbers are not wrong for what was measured; they just are not measuring what the person running it expects.
This needs no particular hardware to see. Run the following from a checkout, which feeds the selection function that machine's topology:
import sys
from unittest import mock
sys.path.insert(0, "Tools/ftscalingbench")
import ftscalingbench
LSCPU = "# cpu,node,core,MAXMHZ\n" + "".join(
f"{c},0,{c//2},{'5200.0000' if c//2 in (4, 5) else '5000.0000'}\n"
for c in range(16)
) + "".join(f"{16+i},0,{8+i},3700.0000\n" for i in range(8))
with (mock.patch("subprocess.check_output", return_value=LSCPU),
mock.patch.object(sys, "platform", "linux")):
print(ftscalingbench.determine_num_threads_and_affinity())
Expected [0, 2, 4, 6, 8, 10, 12, 14], one CPU per performance core. Actual [8, 10].
Any CPU whose performance cores are not all binned to the same clock runs into this. I have only confirmed it on the Intel part above; whether other heterogeneous designs report distinct MAXMHZ values within their fast cluster I have not checked, though where they do, the same filter would keep only the fastest of them.
Splitting performance and efficiency cores at the midpoint between the highest and lowest reported clock handles the uneven binning, since efficiency cores sit far below every performance core on the parts this code is trying to account for. Machines that report one clock for every core, or no clock at all, need to keep accepting everything, which is the case in many virtual machines where MAXMHZ comes back empty.
This only affects people running the benchmark by hand on Linux; it is not part of pyperformance or any automated suite. It does mean that free-threading scaling measurements taken on a recent Intel laptop or desktop may have been collected with fewer threads than intended.
I have a patch and tests for this and will open a PR.
Linked PRs
- gh-155105
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 Tools/ftscalingbench 和 determine_num_threads_and_affinity() 开始,然后运行提供的 lscpu 模拟复现。完成的标准是复现出的拓扑选择 [0, 2, 4, 6, 8, 10, 12, 14],同时均匀的、缺失的或虚拟机的时钟数据仍然被接受;检查与 PR gh-155105 相关的补丁和测试。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- performance, tooling
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 15/100