mcpField
C
CPU Performance Engineering

CPU Performance Engineering

本地服务
github.com开发工具1.2k3 周前更新

关于 CPU Performance Engineering

CPU Performance Engineering 是一个 MCP 服务,让 AI 客户端检索并推理一份 CPU 性能工程阅读清单及其引用的论文、手册和基准测试。面向做性能分析的开发者,可直接粘贴 perf stat 或编译器输出进行解读。

主要功能

  1. 01检索经过筛选的阅读清单及其来源段落
  2. 02解析 perf stat 输出并计算各项比率
  3. 03基于 Top-down 分析定位瓶颈类型
  4. 04解读 gcc 与 clang 的向量化优化提示
  5. 05查看反汇编与源码并给出相关资料

适用场景

  1. 01分析多线程程序无法随线程数扩展的原因
  2. 02根据 perf stat 输出判断时间消耗在哪里
  3. 03查询 Intel 优化手册中关于 store forwarding 的说明

MCP 相关

该项目是 MCP 服务,向 MCP 客户端提供搜索清单、解析性能数据和查询论文与手册段落的工具。服务在本机运行,并在首次启动时构建本地索引。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"usamahz-cpu-perf": {
"command": "uvx",
"args": [
"cpu-perf"
]
}
}
}
启动命令uvx cpu-perf

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypicpu-perf0.1.1

工具

13

收录的工具列表 · 更新于 2 周前

参数类型必填说明
detailenum否brief(默认值):仅在相关时返回精简段落、基准测试和编辑记录。full:返回完整段落及所有相关内容。brief | full
contextany否可选的粘贴输出,与问题一并分析:perf stat(普通格式、-x 或 -j)、perf stat --topdown 或 -M TopdownL1、toplev、gcc -fopt-info / clang -Rpass 提示、汇编或源代码。系统会根据输出计算指标,并使用其中的事件名称、提示和标识符来引导搜索。
sectionany否限制为一个 README 章节编号(1-16)。
questionstring是用户的问题,使用其原话,并包含来源可能使用的技术术语(例如:“为什么我的计数器无法继续扩展?false sharing cache line contention”)。
max_passagesany否要返回多少个来源段落(默认值:brief 为 5,full 为 8)。

详细介绍

cpu-perf

一个 MCP 服务,可让任何 AI 客户端将完整的 CPU Performance Engineering 列表作为可搜索和推理的内容,而不是必须粘贴的一张页面。将它连接到 Claude Code、Codex、Claude Desktop、Cursor 或 VS Code,用于你自己的性能工作:提问、粘贴 perf stat 或编译器输出,然后由客户端自己的模型根据服务返回的内容撰写答案,并引用来源。

它了解两类内容。

  1. 仓库。 按阅读顺序排列的每个条目及其入选理由;观察名单及每一项的晋级条件;列表背后的编辑记录(所有曾考虑但最终未收录的候选项,以及它们未通过的规则;按照七字段规则审查的每个性能数字及其判定;链接核验说明);十四项基准测试及其主张、机器、结果、分析、代码和原始输出;以及编辑规范。这些内容与服务一同打包,加载只需不到一秒。
  2. 来源本身。 首次运行时,服务会读取 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、_PATHHTTP 服务(--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。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。