关于 CPU Performance Engineering
CPU Performance Engineering 是一个 MCP 服务,让 AI 客户端检索并推理一份 CPU 性能工程阅读清单及其引用的论文、手册和基准测试。面向做性能分析的开发者,可直接粘贴 perf stat 或编译器输出进行解读。
主要功能
- 01检索经过筛选的阅读清单及其来源段落
- 02解析 perf stat 输出并计算各项比率
- 03基于 Top-down 分析定位瓶颈类型
- 04解读 gcc 与 clang 的向量化优化提示
- 05查看反汇编与源码并给出相关资料
适用场景
- 01分析多线程程序无法随线程数扩展的原因
- 02根据 perf stat 输出判断时间消耗在哪里
- 03查询 Intel 优化手册中关于 store forwarding 的说明
MCP 相关
该项目是 MCP 服务,向 MCP 客户端提供搜索清单、解析性能数据和查询论文与手册段落的工具。服务在本机运行,并在首次启动时构建本地索引。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
13收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| detail | enum | 否 | brief(默认值):仅在相关时返回精简段落、基准测试和编辑记录。full:返回完整段落及所有相关内容。brief | full |
| context | any | 否 | 可选的粘贴输出,与问题一并分析:perf stat(普通格式、-x 或 -j)、perf stat --topdown 或 -M TopdownL1、toplev、gcc -fopt-info / clang -Rpass 提示、汇编或源代码。系统会根据输出计算指标,并使用其中的事件名称、提示和标识符来引导搜索。 |
| section | any | 否 | 限制为一个 README 章节编号(1-16)。 |
| question | string | 是 | 用户的问题,使用其原话,并包含来源可能使用的技术术语(例如:“为什么我的计数器无法继续扩展?false sharing cache line contention”)。 |
| max_passages | any | 否 | 要返回多少个来源段落(默认值:brief 为 5,full 为 8)。 |
详细介绍
cpu-perf
一个 MCP 服务,可让任何 AI 客户端将完整的 CPU Performance Engineering 列表作为可搜索和推理的内容,而不是必须粘贴的一张页面。将它连接到 Claude Code、Codex、Claude Desktop、Cursor 或 VS
Code,用于你自己的性能工作:提问、粘贴 perf stat 或编译器输出,然后由客户端自己的模型根据服务返回的内容撰写答案,并引用来源。
它了解两类内容。
- 仓库。 按阅读顺序排列的每个条目及其入选理由;观察名单及每一项的晋级条件;列表背后的编辑记录(所有曾考虑但最终未收录的候选项,以及它们未通过的规则;按照七字段规则审查的每个性能数字及其判定;链接核验说明);十四项基准测试及其主张、机器、结果、分析、代码和原始输出;以及编辑规范。这些内容与服务一同打包,加载只需不到一秒。
- 来源本身。 首次运行时,服务会读取 README 中链接的每个来源,以及每个链接背后的主要文档(例如 arXiv 摘要背后的 PDF、供应商着陆页背后的手册、仓库的 README、拉取请求的说明),提取带页码的文本,并据此建立本地全文和语义索引。之后,问题将根据论文、手册和文档作答,而非依赖记忆。
服务不会在此基础上编造任何内容:它会在启动时读取 README、各节草稿和基准测试;README 始终是产品本身,生成的索引也不会提交到任何地方。
连接
你的 AI 客户端会通过 uv 自行启动服务:它运行 uvx cpu-perf,下载发行版并启动服务。如下所示,只需将该命令添加到客户端一次;在终端中运行时,它只会等待客户端连接。(pip install cpu-perf 也可用,并提供相同的 cpu-perf 命令。)
首次启动时会下载依赖项,这可能比某些客户端等待新服务启动的时间更长。先在终端中运行一次 uvx cpu-perf --version,之后每个客户端都能在大约一秒内启动服务。
| 客户端 | 设置 |
|---|---|
| Claude Code | 一条命令 |
| Claude Desktop | 几行配置 |
| Codex(CLI、IDE 扩展、ChatGPT 桌面应用) | 一条命令 |
| Cursor、VS Code | 几行配置 |
| Claude.ai、Claude 移动应用、网页版 ChatGPT | 暂不支持 |
上面列出的每个客户端都会在你自己的机器上启动服务;无需托管任何内容。Claude.ai、移动应用和网页版 ChatGPT 只能连接互联网上的服务,无法连接你电脑上的程序,因此目前无法使用它。
Claude
Claude Code
claude mcp add --scope user cpu-perf -- uvx cpu-perf
Claude Desktop:打开 Settings、Developer、Edit Config,然后在
claude_desktop_config.json 中添加配置。Desktop 并不总能读取 shell 的
PATH,因此请提供 which uvx 输出的完整路径:
{
"mcpServers": {
"cpu-perf": { "command": "/full/path/to/uvx", "args": ["cpu-perf"] }
}
}
ChatGPT
ChatGPT 桌面应用通过其 Codex 主机运行本地服务,配置如下。
Codex
codex mcp add cpu-perf -- uvx cpu-perf
或者,在 ~/.codex/config.toml 中配置(CLI、IDE 扩展和
ChatGPT 桌面应用共用此配置):
[mcp_servers.cpu-perf]
command = "uvx"
args = ["cpu-perf"]
startup_timeout_sec = 120 # room for the first start's downloads
# Codex starts servers with a minimal environment; behind a proxy, pass it on:
# env_vars = ["HTTPS_PROXY", "HTTP_PROXY", "NO_PROXY"]
Cursor 和 VS Code
Cursor(~/.cursor/mcp.json)和 VS Code(.vscode/mcp.json,
键名为 servers,并添加 "type": "stdio"):
{
"mcpServers": {
"cpu-perf": { "command": "uvx", "args": ["cpu-perf"] }
}
}
每个客户端看到的内容
答案采用 Markdown 格式,供模型阅读。Claude Code 和 Codex 在工具返回结构化数据时,只向模型显示这些数据,因此服务默认不返回结构化数据,让每个客户端都能读取相同的文本(--structured-output 可在编程使用时重新启用结构化输出)。每个工具都标记为只读,因此客户端不会在每次调用时都请求批准;读取大型文档即使速度较慢,也会在一分钟内返回,并在后台完成。
然后可以询问,例如:
- 为什么我的多线程计数器在超过 2 个线程后就无法继续扩展?
- 这是我的
perf stat输出;时间都花在哪里了? - gcc 提示“未进行向量化:访问模式复杂”;我该怎么改?
cycle_activity.stalls_l3_miss统计的是什么?- Intel 优化手册对存储转发是怎么说的?
- 给我一条关于 NUMA 的阅读路径,并以一个我可以运行的内容收尾。
- 为什么列表中没有 cppreference?
- “AVX-512 在 Zen 5 上能带来 2 倍性能”是列表会引用的说法吗?
用于你自己的工作
ask 接收问题,以及可选的用户粘贴的context。服务会自行读取该输出,不涉及模型:
perf stat的普通形式、-x和-j形式,包括按 CPU 和按间隔输出:读取到的计数器,以及根据这些计数器计算出的比率(每周期指令数、频率、分支、缓存和 TLB 未命中率、每千条指令的未命中数、停滞周期占比、每秒故障数和上下文切换数),每项都附带公式,并按照 perf 计算自身列的方式计算。混合架构芯片上的 P-core 和 E-core 计数绝不会相互除以对方的计数。- Top-down 第 1 级,来自
perf stat --topdown、-M TopdownL1、AMD 的PipelineL1组或 toplev;以及来自-M TopdownL2的第 2 级。只有当所列来源声明了阈值时,才会根据该阈值标记某一级:Intel 自己的 TMA 指标表中的值,仅应用于 Intel P-core,且每项标记都会附带引用。其他所有情况都只报告测量结果,不作判断。若某一级被标记,答案会指向列表中与之相关的部分:内存受限的运行会指向内存层次结构,前端受限的运行则会指向取指和解码。 - **机器:**当 PMU 和事件名称表明使用的是 Intel、AMD 或 Arm 时,会排除其他厂商硬件和工具相关的来源。
- **可信度:**多路复用的计数器(以及最低运行占比,包括指标组)、未计数或不受支持的事件、汇总了多少个
-I间隔,以及解析器无法读取的行;这些都会列出,而不是靠猜测得出。 - **perf 自身的错误:**缺少指标组、
perf_event_paranoid拒绝访问、未知或不受支持的事件、NMI watchdog:每项都会结合 perf 自己给出的建议重新表述,而不是逐字搜索。 - **gcc
-fopt-info和 clang-Rpass提示:**说明每个循环为何未采用标量方式,并按循环计数;这些提示会引导至列表中的自动向量化相关来源和基准测试。 - 汇编和代码:
objdump -d(可带或不带操作码字节)、gdb 的disassemble、perf annotate和源代码。重要的指令和标识符(gather、原子操作、fence、intrinsic、alignas、restrict)会引导至相应章节,循环的行为也一样:跨迭代累加的浮点数求和,即使提示称循环已向量化,没有-fassociative-math时仍会保持为一条串行加法链(以及在一串标量加法前进行打包乘法时,其汇编形态);提前退出;或从结构体数组中读取字段。
事件名称、提示和标识符随后会引导搜索,因此返回的段落会针对粘贴的输出,而不只是针对问题本身。
每个答案都会说明列表中的哪些来源提供了文本,哪些没有。每个条目都会标记为:已引用(附段落和页码)、已收录于资料库但没有匹配段落(附用于查看内容的 read_source 调用),或在这台机器上未读取(附原因:被阻止、被代理拒绝、尚未获取,或仅有简介的演讲)。模型会被告知,只能根据提供给它的段落将某项说法归于某个来源;未读取的来源只能作为延伸阅读推荐,不能作为引用。问题涉及的所列论文会附上摘要;每个段落都使用列表中的来源标题,而非文档自身的标题,因为后者常常只是“Untitled Document”之类的占位符。
答案默认简短:段落会裁剪至匹配内容;仅当相关时才附上基准测试和编辑记录;每个段落都附有一个 id,可通过 read_source(ref, passage=id) 展开查看完整内容。detail="full" 会返回完整段落及所有相关内容。重复的问题会从缓存中回答,直到资料库发生变化。
首次运行:构建资料库
服务会立即根据仓库中的内容回答问题。与此同时,它会在后台将链接指向的来源抓取到本地资料库:
- 位置:Linux 上的
~/.local/share/cpu-perf、macOS 上的~/Library/Application Support/cpu-perf、Windows 上的%LOCALAPPDATA%\cpu-perf,或CPU_PERF_DATA_DIR; - 耗时:视网络情况和大型手册而定,从几分钟到 15 分钟左右不等;如果客户端关闭了服务,抓取会从停止处继续;
- 大小:包含段落、关键词索引和嵌入向量的一个 SQLite 文件,最多几百 MB;不会保留下载的文件本身;
- 跳过的内容:超大型 PDF 只会索引至页数上限,其余内容会按需读取;扫描版 PDF、压缩的 PostScript 文件和视频没有可供索引的文本(视频会保留标题和描述)。
如需在前台构建并查看进度,请运行
cpu-perf index;cpu-perf status --detail 会列出每个来源及其状态。
多个 MCP 客户端(例如 Claude Desktop、Claude Code 和 Cursor)会共用一个资料库。每隔几分钟,其中一个客户端会负责维护工作;具体由哪个客户端执行,取决于哪个客户端持有数据文件夹的操作系统锁。维护工作包括抓取新的来源、需要刷新的来源或需要重试的来源,为缺少向量的段落生成嵌入向量,并就地更新由旧版本构建的资料库。只有当某个版本改进了特定类型文档的读取方式时,才会重新抓取来源(此版本会将 PDF 跨行断开的单词重新拼接)。刷新失败时,会保留资料库中已有的副本,除非文档已不存在。客户端退出或崩溃时,系统会释放锁;有请求到来时,维护工作会暂停。
一些出版方(ACM、IEEE,以及 Intel 和 Arm 门户的部分内容)会拒绝自动化客户端,或只在浏览器中呈现文档。这些来源会标记为受阻或部分可用,并附上列表中的说明链接,告知原因;回答会引导读者访问该链接。报告会如实反映覆盖情况,不会夸大。
语义搜索使用小型静态嵌入模型
potion-base-8M,该模型只会下载一次。如果没有该模型(处于离线状态,或设置了 CPU_PERF_EMBED_MODEL=none),资料库会退回到仅使用关键词搜索。
版权与礼貌原则
资料库会在用户自己的机器或运营方自己的服务器上,根据列表链接的公开 URL 构建;抓取的内容不会提交、发布,也不会打包进软件包或容器镜像中。抓取器只获取这些文档,会标明自身身份,在访问同一主机的请求之间留出间隔,并在遇到速率限制时降低请求频率。它会像读者打开链接一样读取每个列出的链接,因此除非通过 --respect-robots(CPU_PERF_RESPECT_ROBOTS=1)启用,否则不会查看 robots.txt;如果网站随后禁止访问某个来源,该来源会标记为受阻。
工具
| 工具 | 可回答的问题 |
|---|---|
ask | 某个问题的证据:链接来源中最有用的段落(含页码)、列表中的条目及其入选原因,以及相关时的匹配基准测试和编辑记录。使用 context 时,还会提供粘贴输出中的指标和备注。请先调用此工具。 |
lookup | 对条目、章节、基准测试、记录、备注和基准测试代码进行排序查找,也可在来源文本中查找(scope="sources")。 |
search, fetch | 按 ID 查找文档(条目、章节、基准测试、记录项目、来源段落),并读取其中一篇全文:ChatGPT 深度研究和公司知识使用的组合。 |
get_section | 目录,或按依赖顺序排列的某个章节及其基准测试;对于观察名单,还包括晋级条件。 |
get_entry | 在上下文中查看某个条目:它入选的原因、前后应阅读的内容、它还出现在哪些位置、其基准测试、其中考察的数字、未纳入的替代方案,以及链接备注。 |
reading_path | 某个主题的阅读顺序,最后以可复现该主题的基准测试收尾。 |
get_benchmark | 某项基准测试的主张、机器(七个字段)、结果、分析、限制、代码、构建和运行脚本、原始输出及指标。 |
editorial_record | 某项内容入选或未入选的原因:按规则驳回的项目、按判定结果整理的主张、链接备注。 |
check_evidence | 对性能主张进行七字段审查,并说明列表如何判断类似数字。 |
read_source | 读取一篇链接来源的文本(来自资料库或即时获取);使用 query 时,只返回匹配的段落;使用 passage 时,返回一段全文。 |
read_file | 读取服务提供的任意仓库文件。 |
library_status | 查看当前提供的是哪个列表副本、每日更新的状态、已索引的链接材料数量,以及哪些内容被阻止及其原因。 |
资源: cpuperf://readme、cpuperf://contents、cpuperf://rules、
cpuperf://watchlist、cpuperf://benchmarks,以及模板
cpuperf://section/{number}、cpuperf://entry/{id}、
cpuperf://benchmark/{slug}、cpuperf://file/{+path} 和
cpuperf://source/{id}。
提示词: ask_the_list、study_plan、diagnose(列表自身的方法:
USE 方法、有效的计数器、top-down、roofline,然后是机制)、
audit_claim、reproduce_benchmark 和 review_candidate(依据 CONTRIBUTING.md
对拟议条目进行预审)。
条目 ID(4.3.5、Start here 1.7)遵循 README,且会随其变更;每项输出还会附带 URL,而 URL 不会变。
保持列表更新
每天一次(同一台机器上的所有客户端共用一次请求),服务会向 GitHub
查询列表的最新提交。有更新时,它会下载该提交,只保留列表自身的文件(与软件包打包的文件集合相同),检查这些文件是否能解析为一个不小于当前所提供列表的列表,然后在两次调用之间切换到该版本。新列表新增的链接会在下一次维护时获取;已删除的链接则会从回答中移除。如果某个条目 ID 现在指向了不同来源,get_entry 会将其标记出来。
下载的文件会作为数据读取。不会导入或运行其中的任何内容;写入任何内容之前,都会检查文件大小和路径。无法解析的副本会被停用,并在 library_status 中附注提示升级服务。检出目录(--repo,或从仓库运行)永远不会更新:它就是正在编辑的副本。将 CPU_PERF_AUTO_UPDATE=0 设为 0 可关闭检查;CPU_PERF_UPSTREAM=owner/repo 可改为跟踪某个分支。
它如何保持可信
- 它使用与
misc/scripts/check_format.py相同的语法解析 README; 如果两者出现偏差,测试就会失败;如果解析出的数量与 README 徽章或变更日志中的总数不一致,另一项测试也会失败。 - README 是权威来源。各部分草稿仅提供 Rejected、Claims、Link notes 和 Benchmark proposal 区块,并按文件编号合并。
- 基准测试数据来自一台 Apple M4 Pro;输出会注明这一点,且服务会告知客户端:只有包含全部 7 个字段时,才能引用某个数字。
- 来自来源的文本会用围栏括起,并标记为不可信数据。
- 根据粘贴的输出计算指标时,会严格按照输出所示的方式计算;唯一应用的阈值是 Intel 为 top-down level 1 发布的阈值,每次都会注明引用来源。
- 一组日常问题检索测试集用于保障排序质量:每次更改都必须保持其召回率(
python tests/eval_queries.py path/to/library.sqlite会打印报告)。
获取安全性
只读取仓库中出现的 URL。每个请求和每次重定向都会经过检查:仅允许使用默认端口上的 http 和 https,且主机必须解析为公共地址(不允许环回、私有、链路本地或云元数据地址);连接会固定到经过检查的地址。
下载和解压均有大小限制和时间限制。会遵循 HTTPS_PROXY 和 NO_PROXY。
速度
仓库的所有内容都保存在内存中,每次查找都通过字典遍历完成;文本片段由 SQLite FTS5 和量化嵌入矩阵提供。运行 cpu-perf --selftest,即可查看你自己的计算机上的加载、索引和查询耗时。
配置
| 变量(标志) | 含义 |
|---|---|
CPU_PERF_DATA_DIR (--data-dir) | 库所在的位置。 |
CPU_PERF_EMBED_MODEL (--embed-model) | model2vec 模型 ID,或使用 none 仅进行关键词搜索。 |
CPU_PERF_AUTO_INDEX=0 (--no-auto-index) | 不在后台构建库。 |
CPU_PERF_LIVE_FETCH=0 (--no-live-fetch) | read_source 仅提供已编入索引的内容。 |
CPU_PERF_LIBRARY=0 (--no-library) | 仅使用仓库知识。 |
CPU_PERF_RESPECT_ROBOTS=1 (--respect-robots) | 跳过 robots.txt 禁止访问的内容。默认情况下会读取列出的所有链接。 |
CPU_PERF_REPO (--repo) | 提供检出版本,而非捆绑副本。 |
CPU_PERF_AUTO_UPDATE=0 (--no-auto-update) | 提供已安装的列表副本;不进行每日检查。 |
CPU_PERF_UPSTREAM | 每日检查所跟踪的 owner/repo(例如某个分叉)。 |
CPU_PERF_MAINTENANCE_SECONDS | 维护任务的运行间隔(默认值为 300)。 |
CPU_PERF_STRUCTURED_OUTPUT=1 (--structured-output) | 同时返回结构化数据和输出架构,供程序化客户端使用。 |
CPU_PERF_LIVE_WAIT_SECONDS | 调用在回答“仍在获取”前等待实时读取的时长(默认值为 40)。 |
CPU_PERF_TRANSPORT、_HOST、_PORT、_PATH | HTTP 服务(--transport http)。 |
CPU_PERF_ALLOWED_HOSTS (--allowed-host) | 通过 HTTP 接受的主机名。 |
GITHUB_TOKEN | 不需要;拉取请求说明来自公共 API。 |
通过 HTTP 提供服务
使用 cpu-perf 的人都不需要这个:上面的每个客户端都会在本地启动它。此方式用于运行一个共享实例。该服务支持 Streamable HTTP;在仓库根目录中运行:
docker build -f misc/mcp/Dockerfile -t cpu-perf .
docker run -p 8000:8000 -v cpu-perf-data:/data -e CPU_PERF_ALLOWED_HOSTS=your-host cpu-perf
端点为 /mcp,健康检查端点为 /healthz,并应置于 HTTPS 之后。未设置允许的主机时,服务会拒绝所有发往 localhost 以外主机的请求,从而防止 DNS 重绑定。服务没有身份验证,因此任何知道 URL 的人都能调用这些工具,而这些工具都只读取数据。容器首次启动时会将库构建到 /data 卷中;镜像本身不包含已抓取的文本。公开实例会提供其他人的作品片段及其链接,就像搜索引擎展示摘要一样。
开发
cd misc/mcp
pip install -e ".[test]"
pytest
cpu-perf --selftest
可编辑安装会读取当前检出版本,因此 README 的修改会在下次启动时生效。测试无需联网:爬虫会针对本地夹具网站和确定性嵌入器运行,每日更新则会针对本地 GitHub 替代服务运行。将 CPU_PERF_EVAL_DB 指向已抓取的 library.sqlite 后,检索测试也会针对真实来源运行。
发布
在 pyproject.toml 中设置版本,合并后,再为 main 上的合并提交打上相同版本的标签:
git tag mcp-v0.1.1 && git push origin mcp-v0.1.1
.github/workflows/mcp-release.yml 会构建、测试并通过可信发布发布到 PyPI。首次发布前需要执行一次:在 PyPI 上为项目 cpu-perf 添加待处理发布者,所有者设为 usamahz,仓库设为 cpu-performance-engineering,工作流设为 mcp-release.yml,环境设为 pypi。GitHub 会在首次运行时创建 pypi 环境。
发布候选版本(例如 0.1.1rc1)也以相同方式打标签;只有明确按版本请求时才会安装,例如 uvx [email protected],因此测试候选版本不会影响使用最新正式版的人。
随后,同一工作流会根据 server.json 将该版本列入 MCP Registry,并使用工作流自身的 GitHub 身份登录,因此发布无需其他步骤。server.json 中的版本与 pyproject.toml 相同。Registry 会通过查找 README 中 PyPI 页面所显示的这一行,验证 PyPI 包确实属于该条目,因此请将其保留在这里:
mcp-name: io.github.usamahz/cpu-perf
许可证
与仓库相同,采用 MIT 许可证。wheel 包含仓库文件及其 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。