十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

x86服务器 SPEC CPU2017 安装、cfg 与 runspec 实战

x86服务器 SPEC CPU2017 安装、cfg 与 runspec 实战 SPEC CPU2017 这套东西第一次接触的人多半是被安装两个字骗进来的。下载一个 ISO、跑一个 install.sh听起来跟装个数据库差不多真正上手才发现从挂载到出分之间隔着一整条链路编译器版本、cfg 配置文件的字段、runspec 的参数组合、跑完之后的 ratio 怎么算任何一环出问题都只会给你一句看不懂的报错。这篇文章把我自己在 x86 服务器上反复装、反复跑 speccpu2017 的过程完整梳理一遍重点放在安装与使用这两个动作上——ISO 怎么挂、install.sh 会问你什么、cfg 文件哪些字段必须改、runspec 从冒烟测试到正式出分怎么敲、以及编译和运行阶段最容易翻车的几个位置。全文假设你已经通过正规渠道拿到了 ISO 并接受了它的许可条款后面的操作都在拿到文件之后展开。1. 先把 SPEC CPU2017 这套东西的脾气摸清楚1.1 它不是一个软件是四个套件加一套打分规则很多人以为 SPEC CPU2017 是一个跑分程序装上以后敲一条命令就出分。实际它是四个互相独立的套件加一套打分规则SPECspeed 2017 Integer10 个基准程序、SPECspeed 2017 Floating Point13 个、SPECrate 2017 Integer10 个、SPECrate 2017 Floating Point13 个。同一个算法在 speed 和 rate 里会出现两次编号和源码都不一样比如整数里的600.perlbench_s和500.perlbench_r是两个独立的目录、两套独立的源码和数据集后缀_s/_r就是它们的身份标识。这意味着你在 cfg 里针对600.perlbench_s做的一切定制对500.perlbench_r完全不起作用要改就得分别改。刚开始我不理解这个设计觉得重复劳动后来才明白speed 和 rate 的负载特征不同需要不同的编译开关把它们拆成两套源码反而让配置更清晰。安装完之后benchspec/CPU/下面会摊开几十个目录每个目录里都带自己完整的src、data、spec三件套这就是它动辄占几个 G 的原因。还有一个容易忽略的点SPEC CPU2017 的源码和数据集是受许可约束的产品不是开源项目。你能在自己机器上编译、运行、看结果但把编译产物或者数据集二次分发是另一回事。商用场景下要留意这一点学术和研究用途相对宽松但具体边界还是要看拿到 ISO 时接受的那份条款。我在这里只讨论技术操作不涉及获取途径。1.2 SPECspeed 与 SPECrate测延迟还是测吞吐这两个词最容易混。SPECspeed 测的是一件事做多快本质上更接近单任务延迟一次只算一个基准程序看它多长时间跑完再把参考机耗时除以实测耗时得到 ratio最后对一批 ratio 取几何平均就是SPECspeed2017_int_base这种总分。规则允许的情况下对本身支持 OpenMP 的基准程序可以用--threads给多线程。SPECrate 测的是单位时间能做多少件事也就是吞吐。它的做法是在同一台机器上同时起 N 个独立的进程副本每个副本跑同一份负载最后用副本数 × 参考耗时 / 实测耗时得到 ratio。所以 rate 的分数和--copies直接挂钩8 副本和 64 副本测出来的数字不是一回事跨平台比分数时第一个要确认的就是对方用了多少副本。这个区别直接决定了你怎么配机器。跑 rate 的时候多副本会同时抢 LLC 和内存带宽超线程在这种场景下往往是负收益把 SMT 关掉、一个物理核跑一个副本通常更好看跑 speed 的时候少数能吃多线程的基准程序反而希望 SMT 打开让线程能塞进超线程里。我见过不少人拿 speed 的调优手法去跑 rate结果分数比预期低一截还以为是机器有问题其实就是副本数没算对。1.3 base 和 peak 差在哪什么时候只需要跑 basebase 是有约束的公平赛道同一套件内所有基准程序必须用一致的优化选项不能针对某一个程序单独下猛药允许的优化级别也有上限。peak 是放开手脚你可以给602.gcc_s单独加一组对它有利的开关给627.cam4_s换另一组只要能通过正确性校验就行。对绝大多数使用场景——比较两代 CPU、验证编译器版本升级带来的收益、评估采购方案——只跑 base 就够了。peak 的调优工作量是指数级的而且 peak 分数高度依赖你花了多少时间堆开关可比性反而不如 base。我自己的做法是内部评估只跑--tunebase --sizeref --iterations3只在需要对外提交正式结果时才动 peak。2. 装之前的两笔账机器够不够、编译器选哪个2.1 内存与磁盘的经验估算SPEC CPU2017 官方给出的内存底线不高但这只是能跑起来的底线不是跑得舒服的底线。实际跑--sizeref时621.wrf_s、627.cam4_s、628.pop2_s这几个浮点程序单副本的常驻内存就能到 1 GB 以上跑 rate 时按副本数线性叠加64 副本的场景下几百 G 内存眨眼就没了。我的经验值是这样的使用场景内存建议说明只跑 test 尺寸冒烟测试8 GB够用但别指望跑 ref单套件 ref--copies116 GBintspeed 这类基本不会 OOM单套件 ref--copies8~1664 GBrate 场景的常见配置全套件 ref高副本数128 GB 起建议按物理核数 × 2 GB 估算磁盘这块ISO 本身几个 G安装解压后在 34 GB 量级但真正吃空间的是编译产物和运行日志。每个基准程序的build/目录里会同时留着源码副本、目标文件和可执行文件四个套件全编一遍再跑几轮轻轻松松吃掉二三十个 G。我一般直接留 100 GB省得跑到一半因为磁盘满导致specmake报一堆莫名其妙的错。磁盘写满这个坑特别阴——报错信息通常出现在编译阶段看起来像是源码问题实际是没地方写.o文件。2.2 GCC 版本别追新选 9 到 12 最省心编译器版本是第二个要先定下来的事。SPEC 提供的示例 cfg 通常按发行版默认的 GCC 写好而发行版默认的 GCC 往往比 SPEC 官方验证过的版本更新。新版本 GCC 做了两件对跑分很不友好的事一是把一些原来只是警告的诊断提升为错误二是默认行为变了比如更强的最严格别名规则、默认打开某些新优化导致某些基准程序直接编不过或者算错。我自己的选择范围是GCC 9 到 GCC 12。GCC 8 及以下在部分浮点程序上优化不足GCC 13 以后新引入的诊断偶尔会和 SPEC 自带的specmake打架。如果你的机器上只有很新的 GCC有几个办法装一个老版本的 GCC 单独放一个路径在 cfg 里把CC/CXX/FC写成绝对路径指过去或者在 cfg 里加-Wno-error之类的开关压掉新诊断。前者的确定性更高我更推荐。Clang 也能跑但要注意FC那一项——SPEC CPU2017 里浮点套件大量使用 FortranClang 本身不带 Fortran 前端你需要额外配flang或者让FC指向 GCC 的gfortran。混用编译器的组合不是不行但一旦出现数值校验失败排查起来会比纯 GCC 麻烦好几倍。首次上手建议全套 GCC等链路跑通了再考虑换组合。2.3 依赖包清单与检查命令装之前把这些包确认一遍能省掉后面一半的报错gcc、g、gfortran三个都要gfortran最容易被漏掉libgfortran运行库有些发行版拆成单独的包make、binutils给specmake兜底perlrunspec本身依赖 PerlSPEC 包里自带specperl但系统里有一个 Perl 会更稳numactl跑 NUMA 机器绑定用cpupower调频率策略用一条命令快速自查for c in gcc g gfortran make perl numactl; do printf %-10s $c; command -v $c || echo MISSING donecommand -v比which可靠在容器或者精简系统里which可能根本没装。如果在容器里跑还要确认两件事一是 CPU 亲和性没有被 cgroup 限死二是--copies不能超过容器实际能用的核数否则 SPEC 会直接判定运行无效。3. 从 ISO 到可用的工作目录install.sh 到底做了什么3.1 挂载 ISO 与安装目录规划拿到 ISO 之后的第一步是挂载。别急着解压到别的地方install.sh需要看到完整的 ISO 目录结构mkdir -p /mnt/speciso mount -o loop,ro cpu2017-1.1.x.iso /mnt/speciso ls /mnt/specisols出来应该能看到install.sh、benchspec、tools、Docs这些顶层条目。如果只看到一个巨大的镜像文件说明你挂错了对象——有些发行版会把 ISO 用其它工具再包一层先确认文件类型。安装目录我习惯放在数据盘而不是系统盘因为后面编译产物会把目录撑得很大而且需要频繁读写。安装路径里不要有空格和中文SPEC 的脚本对路径的处理在有些环节不够健壮空格会引发一些很难定位的问题。我一般用/opt/cpu2017或者数据盘下的/datadisk/cpu2017。顺带说一句-o loop,ro里的ro只读挂载能防止后续误操作改到 ISO 内容同时也能避免某些系统在 ISO 被写之后校验失败。3.2 install.sh 的交互过程与我没有选默认值的地方进到挂载点直接执行cd /mnt/speciso ./install.sh脚本会先打印一段欢迎信息然后逐项问你问题。核心是两三个第一个是安装目标目录。默认值是当前目录下的cpu2017如果你在/mnt/speciso里执行那就是把文件复制到/mnt/speciso/cpu2017这显然不合适。我一般在这里手动输入/opt/cpu2017。如果目标目录已经存在脚本会提示覆盖还是退出覆盖会清掉你之前的 cfg 和编译产物所以升级版本时千万别直接覆盖换个新目录。第二个是是否安装/构建工具链。SPEC 在 ISO 里带了预编译好的specmake、specinvoke、specdiff、specperl等工具脚本会问你沿用现有的还是重新构建。除非你的平台比较冷门比如某些非 x86 架构或者预编译工具在你的系统上跑不起来否则沿用预编译版本是最省事的。重新构建需要系统里有一套能用的编译环境构建失败的话脚本会留下一个半成品目录比直接用预编译还麻烦。安装过程本质上是把 ISO 里的内容复制到目标目录同时根据你的平台调整一些脚本里的路径变量。耗时主要看磁盘速度几个 G 的内容NVMe 上通常一分钟内完事。装完脚本会打印一句提示告诉你接下来怎么做——通常是让你source shrc。3.3 装完之后的目录地图benchspec、bin、config、result装完以后一定要先花五分钟把目录结构看明白后面所有操作都在这几个目录之间来回跳cd /opt/cpu2017 source shrc lsshrc是环境脚本执行之后 PATH 里会多出安装目录的bin同时会设置几个 SPEC 相关的环境变量。每次开新终端都要重新 source忘了就会遇到命令找不到的低级问题。目录分工大致是这样目录作用你会不会常去bin/runspec、specmake、specperl等命令每次跑分都会用到benchspec/CPU/各基准程序的源码、数据集、编译目录排查编译错误时必去config/示例 cfg 文件你写的 cfg 放这里配置阶段常去result/所有输出.txt、.csv、.html、.log跑完必看tools/工具链和平台相关脚本基本不用管Docs/用户手册和 run rules遇到规则问题才翻benchspec/CPU/下面每个基准程序目录里src/是源码data/是数据集build/是编译产物exe/是可执行文件run/是运行时的临时目录。编译报错时的日志不在你们以为的地方——它藏在build/build_base_ext-平台.0000/里面而且每个基准程序一个目录得自己去找。4. cfg 文件才是真正的操作台4.1 从 Example 配置抄一份骨架每次跑分都要指定一个 cfg 文件。安装自带的config/目录里有一堆Example-linux-x86-gcc-*.cfg直接拿其中一个改是最快的路径但有几个字段必须动否则要么跑不起来要么跑出来的结果没有任何意义。先看一眼有哪些示例ls config/Example-*gcc*挑一个名字里有x86_64和gcc的复制成自己的文件cp config/Example-linux-x86_64-gcc.cfg config/my-gcc.cfg不要直接改示例文件——那是对照用的参考改乱了以后遇到问题没有 baseline 可比。自己的配置统一放到config/下命名带上前缀方便识别。cfg 的语法有两层顶层是一行一个键 值的全局设置比如iterations、label、output_format然后是分节分节名形如defaultdefaultdefault:三段分别对应 benchmark、tune、extension 的匹配条件。default是通配符所以defaultbasedefault:表示所有基准程序、base 调优、任意 extension。分节内的键值会覆盖全局设置这就是针对单个基准程序定制编译选项的机制。4.2 编译选项怎么定OPTIMIZE 与 EXTRA_* 的分工编译选项分两层理解这个分工能帮你少走很多弯路。第一层是OPTIMIZE、COPTIMIZE、CXXOPTIMIZE、FOPTIMIZE分别对应通用、C、C、Fortran 的优化开关第二层是EXTRA_OPTIMIZE、EXTRA_COPTIMIZE等它们会被追加在对应开关之后。这个追加特性非常关键。因为很多基准程序的spec定义里已经硬编码了一些必需开关比如某个宏定义、某个兼容性标志如果你在OPTIMIZE里写一套完全不同的选项可能把那些必需开关冲掉而用EXTRA_COPTIMIZE追加就不会覆盖原有内容。我自己的习惯是基础选项写在OPTIMIZE系针对单个程序的微调一律用EXTRA_*系。另一个必须提的开关是-fno-strict-aliasing。SPEC 的不少源码写于严格别名规则收紧之前开高优化级别后容易被优化器做出错误假设表现为编译通过、运行崩溃或者数值校验失败。base 场景下直接全局加上它代价是损失一点性能换来的是稳定性。基地址模型也很常踩。600.perlbench_s这类程序在某些平台上需要-m64之类的开关SPEC 提供了PORTABILITY系列键专门放这些兼容性选项它们会在合适的位置被加入编译命令。示例 cfg 里已经帮你填好了大部分不要嫌麻烦删掉那些看起来没用的宏定义往往就是某个平台能编过的唯一原因。4.3 一份可以直接改改就用的 cfg 样本下面这份是我在 x86 服务器上常用的骨架字段名和结构与官方示例保持一致你按自己的路径和编译器版本替换即可# my-gcc.cfg action run tune base ext gcc12 output_format all label internal-test iterations 1 size test defaultdefaultdefault: CC /usr/bin/gcc CXX /usr/bin/g FC /usr/bin/gfortran OPTIMIZE -g -O2 -fno-strict-aliasing COPTIMIZE -O3 -marchnative -fno-strict-aliasing CXXOPTIMIZE -O3 -marchnative -fno-strict-aliasing FOPTIMIZE -O3 -marchnative EXTRA_LIBS -lm几个细节值得说明。ext是扩展名它决定编译产物目录的后缀build_base_gcc12-平台.0000不同的ext值可以让你在同一份源码上并存多套编译产物方便对比不同编译器或不同开关的效果——这是我用得最多的一个字段做编译器版本横评的时候特别有用改一次ext就等于开一条新赛道互不干扰。-marchnative在单机自测时很方便但它会让结果绑定到具体这台机器换一台 CPU 微架构不同的机器重跑数字就不可比了。如果要做跨机型对比把这个开关换成明确的-march具体微架构比如-marchskylake-avx512或者-marchznver3。EXTRA_LIBS -lm是给数学库兜底某些精简系统上不加会链接失败。至于针对单个基准程序的微调写法是这样605.mcf_sbasedefault: EXTRA_COPTIMIZE -fno-tree-loop-vectorize分节名里第一个字段可以直接写 benchmark 编号匹配到就生效。调优阶段最耗时间的就是这一块跑一个基准程序、看一次结果、改一个开关来回几十轮很正常所以只建议在需要 peak 分数的时候折腾。5. runspec 的用法从冒烟测试到正式出分5.1 先用 test 尺寸把链路跑通配置写完第一件事绝对不是直接上 ref 跑全套那样出了问题你要等几个小时才能看到报错。先用 test 尺寸跑单个基准程序cd /opt/cpu2017 source shrc bin/runspec --configmy-gcc.cfg --sizetest --tunebase \ --iterations1 --noreportable 605.mcf_s这里三个参数值得解释。--sizetest用的是最小的数据集几分钟就能出结果--noreportable表示这次运行不追求可用于正式报告的合规性它允许你用小数据集、少迭代次数、甚至并行跑多个程序代价是结果不能拿出去当正式成绩605.mcf_s指定只跑这一个基准程序用来验证编译链路。选605.mcf_s也是有讲究的。它是整数套件里比较干净的一个——C 语言、依赖少、编译快能最快暴露编译器路径配错、specmake找不到、数据集缺失这类基础问题。等它跑通了再回到全量运行成功率会高很多。如果这一步就报错了别怀疑配置逻辑先看三件事gcc路径是不是绝对路径且真实存在、benchspec/CPU/605.mcf_s/下面有没有数据、result/目录有没有写权限。我遇到过一次跑不动的原因纯粹是挂载点用了noexec二进制根本没法执行。5.2 单跑一个 benchmark 定位问题冒烟测试过了之后建议再单独跑一个浮点基准程序因为浮点套件会用到FC和 Fortran 运行时整数套件跑通不代表浮点能跑bin/runspec --configmy-gcc.cfg --sizetest --tunebase \ --iterations1 --noreportable 603.bwaves_s这一步能暴露gfortran路径错误、libgfortran缺失、Fortran 优化开关不兼容这类问题。我建议整数和浮点各挑一个跑通再去打全套这比直接跑全套省下的时间多得多。跑完之后用--actionvalidate单独做一次正确性校验也是好习惯bin/runspec --configmy-gcc.cfg --sizetest --tunebase \ --actionvalidate 603.bwaves_svalidate只检查已有可执行文件的输出是否与期望值一致不重新编译不重新运行速度很快。它回答的问题是我改的编译选项有没有把结果算错这在调-O3、-ffast-math这类激进开关时特别重要——性能提升可能只是因为你把精度算没了。5.3 全量 ref 运行的命令与耗时预期正式的运行命令是这样bin/runspec --configmy-gcc.cfg --sizeref --tunebase \ --iterations3 --reportable --output_formatall intspeed--sizeref是唯一被允许用于正式成绩的数据集--iterations3会跑三轮并取中位数--reportable打开合规检查要求 ref 尺寸、至少三轮、配置文件完整--output_formatall让结果同时输出 txt、csv、html 三种格式。最后一个参数是套件名可以写intspeed、fpspeed、intrate、fprate也可以一次写多个或者写all。耗时要有心理准备。单套件 ref 跑三轮在主流服务器上通常需要几个小时四个套件全跑一遍一整天是很正常的。别在跑到一半的时候去干别的重活——SPEC 对运行环境很敏感同一台机器上并行做别的事情会直接影响测量结果尤其是你正在做横向对比的时候。跑 rate 还要额外指定副本数bin/runspec --configmy-gcc.cfg --sizeref --tunebase \ --iterations3 --reportable --copies32 intrate--copies的取值要和你机器的物理核数对齐超了会导致资源争抢分数不升反降。如果不想手动数核可以用--copies留空让 SPEC 自己判断但自动判断在某些容器环境下不准我还是倾向手动指定。5.4 跑完以后结果文件怎么看所有输出都在result/下文件名形如CPU2017.时间戳.label.txt。txt 是给人看的里面是每个基准程序一张表列名含义Benchmark基准程序编号和名字Ref Time参考机耗时由套件固定给出你不要去改它Run Time你这台机器的实测耗时Ratio上两者的比值越大越快最后会给出一个几何平均值就是SPECspeed2017_int_base这种总分。几何平均而不是算术平均是为了避免某个特别快的基准程序把总分拉飞所以你看到的分数量级和单个 ratio 是同一档的。.csv是给脚本解析用的做自动化报告的时候用得上.html适合发给别人看还有一个.log文件记录了整个运行过程的细节编译命令、运行命令、环境变量都在里面。排查问题时.log才是第一现场txt 里只告诉你失败了log 里才有失败前最后执行的命令是什么。6. 我踩过的坑以及每个坑的排查顺序6.1 编译阶段高版本 GCC 把警告当错误最典型的表现是编译到一半停下来报错信息里出现error:但紧接着的内容看起来像是提示而不是错误。这几乎可以断定是新版 GCC 把某个诊断默认提升为 error 了。定位方法很直接在benchspec/CPU/bench/build/build_base_ext-平台.0000/里找到make.out或者类似的日志文件里面完整记录了失败那一次的命令行。不要急着去改源码源码是受校验的改了之后validate会失败。正确的解法是在 cfg 里针对这个基准程序加抑制开关620.omnetpp_sbasedefault: EXTRA_CXXOPTIMIZE -Wno-error -Wno-deprecated-declarations-Wno-error是通用解法把警告当错误这个行为关掉代价是可能漏掉真正的隐患但在跑分场景下这个取舍是划算的。更稳妥的办法是换成老版本 GCC从根上避开这些问题。6.2 链接阶段找不到 libgfortran 和 libm编译通过但链接失败报cannot find -lgfortran或者undefined reference to ...基本都是运行库缺失或者路径不对。先用一条命令确认库在不在ldconfig -p | grep -E gfortran|libm\.so如果输出里没有libgfortran.so装对应的包就好注意包名在不同发行版里不一样有的叫libgfortran5有的叫libgfortran有的是跟着gcc-gfortran一起装的。如果库存在但链接器找不到说明库路径不在默认搜索路径里在 cfg 的LDFLAGS里补上-L库路径或者在 cfg 里显式指定FC的绝对路径——SPEC 有时候会根据FC的位置去反推库路径把gfortran写成绝对路径能顺带解决一部分链接问题。还有一种情况是 32 位库缺失。虽然现在基本都跑 64 位但如果 cfg 里基地址模型没配好编译器可能尝试走 32 位路径报出来的错看起来像源码问题实际是缺库。检查一下PORTABILITY里的-m64之类的开关有没有被改掉。6.3 运行阶段OOM 被 kill 和结果 invalid跑 rate 的时候最容易遇到进程被系统杀掉。日志里的表现是某个副本突然消失或者出现Killed字样。原因通常是内存不够dmesg里能看到 OOM killer 的记录。解法有两个方向降低--copies或者给机器加内存。别指望 swap 能救场一旦开始换页跑出来的时间就没有参考价值了即使没被 kill 也该判无效。另一个高频问题是结果被判 invalid。常见触发条件有几个没有满足--reportable的前提用了 test 尺寸、迭代次数不够运行过程中系统负载发生了变化有人登进来干了别的活机器名、CPU 信息在运行过程中发生了变化容器环境下偶尔会出现数值校验没通过改了大量浮点优化开关排查 invalid 的顺序是先看 log 里 harness 给出的具体无效原因那条信息通常很明确再去核对 cfg 里的iterations和size最后才怀疑环境和源码。我遇到过的最坑的一次 invalid 是因为跑分期间主机名被 DHCP 改了log 里只写了一句结果校验失败找了半天才发现。6.4 环境阶段PATH、noexec 挂载与权限这类问题在冒烟测试阶段就该暴露。三个高频点PATH 问题。忘了source shrc会表现为runspec: command not found或者更隐蔽一点——specmake找到了系统里那个同名或者功能类似的make编译出来的行为不对。养成每次开终端先source /opt/cpu2017/shrc的习惯或者把这一行写进~/.bashrc。noexec 挂载。有些系统的安全策略会把某些挂载点设成noexecISO 挂上去之后二进制文件无法执行表现为一个非常含糊的权限错误。用mount | grep speciso看看挂载选项里有没有noexec。权限问题。install.sh需要往目标目录写文件如果你的账号对目标目录没有写权限脚本会在中途失败并可能留下不完整的安装。不要用 root 装完再用普通用户跑——result/和build/目录的属主会不对普通用户没法写。要么全程用同一个账号要么装完把目录属主改对。7. 分数稳定下来靠的是系统侧不是编译器7.1 频率、SMT、NUMA 三个开关的实际取舍同一个平台、同一份 cfg跑两遍差个百分之几是很正常的但如果差了百分之二十那一定是系统侧没管住。频率是第一位的cpupower frequency-set -g performancepowersave或者ondemand策略下CPU 会在空闲时降频而 SPEC 的负载有明显的阶段性降频会让测量结果忽高忽低。设成performance之后还要看具体情况决定要不要关睿频——睿频带来的提升在散热条件不同的机器上不一致做横评时关掉更公平做单机极限性能测试时开着更接近真实使用。我自己的做法是做横评时关、出内部性能上限时开。SMT 的取舍前面提过了跑 rate 关掉跑 speed 看情况开着。NUMA 是第三个开关多路机器上如果进程在 A 节点、内存在 B 节点跨节点访问的延迟会明显拖慢结果。做法是运行前绑定numactl --cpunodebind0 --membind0 bin/runspec --configmy-gcc.cfg \ --sizeref --tunebase --iterations3 --reportable --copies16 intrate如果要做全机测试就让副本均匀铺满所有节点用--copies等于总物理核数同时关掉自动 NUMA 平衡避免运行中内存在不同节点之间漂移。7.2 ratio 和 geomean 的读法拿到结果之后最容易被误读的是两件事。第一是把不同套件的分数直接比大小SPECspeed2017_int_base和SPECrate2017_fp_base是两个完全不同的量纲放在一起比较没有任何意义就像拿每秒能送多少件快递和送一件最远要多久比大小。第二是忽略 base 和 peak 的差别。你跑的是 base看到别人报的是 peak两者差个百分之十几甚至几十都正常直接对比就是在拿苹果比橘子。看别人的成绩时先确认四个信息哪个套件、base 还是 peak、副本数或线程数多少、机器是什么配置。缺了任何一个那个数字就只能当参考不能当结论。几何平均的含义也要清楚它是所有基准程序 ratio 的连乘开方。这意味着一个特别差的 benchmark 会把总分明显拉低而一个特别好的 benchmark 拉高总分的效果有限。所以分析结果时要往下看单个 benchmark 的 ratio找到拖后腿的那几个往往能定位到具体问题——比如某个程序的内存访问模式对你的 NUMA 配置格外敏感。7.3 除了跑分这套东西还能拿来干什么很多人跑完一次就把它丢在一边了实际上这套基准在几个场景里挺有用。编译器升级验证是我用得最多的同一个平台、同一份 cfg只改CC的路径跑一遍 base就能看出新版本编译器在这个工作负载上到底带来了多少收益比看 release notes 靠谱得多。前面提到的ext字段在这里就派上用场了两套编译产物可以并存对比。服务器选型也常用到。采购前拿两台候选机器跑同一套 base 配置重点看 intrate 和 fprate因为真实业务里并发吞吐往往比单任务延迟更接近实际体感。这时候要注意把频率策略、SMT、NUMA 全部对齐否则测出来的差异可能来自配置而不是硬件。还有一个偏冷门但实用的用法用它来验证系统调优的效果。改一个内核参数、换一种内存插槽布局、调整 BIOS 里的电源策略跑一遍 test 尺寸的 rate 就能看出趋势。test 尺寸虽然不能出正式成绩但做相对比较够用了而且快很多。我一般用--sizetest --noreportable --copies核数做这种快速验证一轮下来十几分钟改一次参数跑一次迭代效率比等 ref 快得多。最后分享一个小技巧关于 cfg 的版本管理。cfg 文件是纯文本跑分结果又高度依赖它所以我会把每次正式跑的 cfg 连同结果目录一起归档文件名里带上日期和关键参数。过几个月回头想复现某个数字的时候你会感谢当时多花的那一分钟。
返回列表