news 2026/9/17 1:42:42

Hygon C86 7280 UnixBench 基准测试与调优实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hygon C86 7280 UnixBench 基准测试与调优实战

去年底接手一台 Hygon C86 7280 的单路机器,任务很直接:判断它能不能扛住我们那套 Java 后端加 Redis 的组合。团队里有人主张拿 JMeter 直接压业务接口,我拦了一下——业务压测出来的数字里混着框架开销、GC、连接池、数据库的账,一旦结果不理想,你分不清是机器的锅还是代码的锅。所以我习惯先做一层系统底座的基准测试,把 CPU 整数浮点、内存带宽、进程调度、系统调用这几条通路的底子摸清楚。UnixBench 干的就是这个活:它不测业务,只测一台 Unix/Linux 机器最原始的那几项能力,跑完给你一张分项清单和一个总指数。这篇就是我在 Hygon C86 7280 上从编译、调优、跑分到读数的完整过程,包括踩过的编译坑、并发数怎么选,以及为什么 32 核的系统指数只有单副本的 5 倍多——这几件事想明白了,UnixBench 才不会退化成一串拿来吹牛的漂亮数字。

1. 为什么我在这台 Hygon C86 7280 上先跑 UnixBench 而不是直接上压测工具

很多人对 UnixBench 的印象停留在"一个老掉牙的跑分脚本",觉得它当年给 SPARC 工作站设计的那套东西早该淘汰了。这个判断一半对一半错。错的部分在于:UnixBench 的分项设计其实非常"系统视角",它把一台机器拆成整数、浮点、进程、管道、文件、系统调用六条通路分别打分,正好覆盖了我们排查性能问题时最常怀疑的那几个方向。对的部分在于:它的绝对值确实没有物理意义,离开版本、参数和对照机,任何单个分数都是废话。

1.1 UnixBench 的分项到底在测什么

UnixBench 5.1.3 跑完后会打印十来行分项,每行格式是"结果 基准值 Index"。搞不清每项压的是什么,读数就只能靠猜。

  • Dhrystone 2 using register variables:整数综合运算,递归、过程调用、字符串比较混在一起,主要压整数 ALU 和编译器优化水平。它对编译选项极其敏感,同一个机器用-O2-O3能差出 20% 以上。
  • Double-Precision Whetstone:双精度浮点,压浮点单元和指令译码。这个测试偏老,现代 CPU 上主要反映单核浮点吞吐。
  • Execl Throughput:每秒能完成多少次execl调用,压的是进程创建路径的前半段。
  • File Copy 1024 / 256 / 4096:三个不同缓冲区大小的读写拷贝。这里很容易误会成"测磁盘",实际上它读写的文件基本落在页缓存里,反映的是内存带宽加 Linux 页缓存效率。
  • Pipe Throughput:往管道里灌数据的吞吐,压内存拷贝和读写系统调用。
  • Pipe-based Context Switching:两个进程通过管道来回唤醒,压调度器和内核上下文切换成本。
  • Process Creation:完整的fork+exec+wait流程,比 Execl 更贴近真实的服务 spawn 行为。
  • Shell Scripts (1 concurrent) / (8 concurrent):启动 shell 执行一段简单脚本的次数,反映解释器启动和可执行文件加载成本。
  • System Call Overhead:跑一堆几乎不做事的系统调用(如getpid),纯粹测内核进出代价。内核加固(各种漏洞缓解)对这项影响最大。

每项都有一个来自 1990 年代 SPARCstation 20-61 的基准值,公式很朴素:

Index = (本次结果 / 基准值) x 10 系统指数 = 全部子项 Index 的几何平均

基准值我整理在下面这张表里,后面算分要用:

子项基准值单位
Dhrystone 2 using register variables116700.0lps
Double-Precision Whetstone55.0MWIPS
Execl Throughput43.0lps
File Copy 1024 bufsize 2000 maxblocks3960.0KBps
File Copy 256 bufsize 500 maxblocks1655.0KBps
File Copy 4096 bufsize 8000 maxblocks5800.0KBps
Pipe Throughput12440.0lps
Pipe-based Context Switching4000.0lps
Process Creation126.0lps
Shell Scripts (1 concurrent)42.4lpm
Shell Scripts (8 concurrent)6.0lpm
System Call Overhead15000.0lps

注意:Shell Scripts (8 concurrent)这一项只在并发数达到 8 及以上时才会出现在报告里。这就是为什么你跑单副本看到 11 行、跑-c 32却看到 12 行,不是脚本出错了。

1.2 先搞清楚被测对象:C86 7280 的硬件画像

跑分之前必须把机器画清楚,否则后面看到异常值你无从判断是配置问题还是硬件特性。这台机器我拿到手先跑了三条命令:

lscpu numactl -H dmidecode -t memory | grep -E "Size|Speed|Locator"

lscpu的结果和公开资料描述的规格基本吻合:单路封装,32 个物理核、64 个逻辑线程(开启 SMT),基础频率 2.0GHz 级别,加速频率可到 3.0GHz 左右,L3 缓存 64MB,4 个 NUMA 节点(每节点 8 核),内存 8 通道 DDR4-2666。numactl -H能看到节点间访问延迟差异,这台机器远端节点延迟大概是本地节点的 1.4 到 1.6 倍。

这几个数字直接决定了后面读数的基准预期:64 个逻辑线程意味着-c 64是理论上限,但整数密集型测试在 SMT 上拿不到线性收益;4 个 NUMA 节点意味着文件拷贝、管道这类内存敏感项一旦跨节点,分数会被拖下来;8 通道 DDR4-2666 的理论带宽约 170GB/s,这是文件拷贝类测试的物理天花板。

提示:厂商规格表和实际机器经常不一致,尤其是 BIOS 里内存降频、通道数没插满、NUMA 被关成 interleave 的情况。测之前一定以lscpunumactl -H的现场输出为准。

1.3 三条必须先定死的规则

我见过太多"跑分吵架"的场面,追根究底基本都是三件事没约定好:

  1. 版本。UnixBench 5.1.3 是流传最广的版本,但 GitHub 上有好几个 fork,Makefile 默认优化级别、是否默认开启图形测试、Index 计算脚本都有细微差别。我的做法是把源码目录整体打包存档,报告里写清楚 commit hash。
  2. 编译选项。Dhrystone 这一项对-O级别极其敏感。如果要横向对比不同机器,必须锁死同一个 Makefile、同一个 GCC 版本。我用的是系统自带 GCC,不做额外优化,只加-fcommon让它在 GCC 10 之后能编过(下一节展开)。
  3. 负载条件。跑分前十分钟关掉所有非必要的系统服务、监控 agent、定时任务;确认uptime的 1 分钟负载接近 0;确认 CPU 调频策略是 performance。这三条不做,重复跑出来的差异能到 15% 以上。

2. 编译阶段的坑:GCC 10 之后 UnixBench 5.1.3 起不来

UnixBench 5.1.3 最后一次实质性更新是 2014 年前后,代码风格停留在那个年代。放到现在的发行版上,直接make大概率是编不过的。我在 C86 7280 上就踩了三个坑,记下来省得你重走一遍。

2.1 依赖清单:少一个 libX11 就会中断编译

基础的编译依赖其实很少:

# Debian / Ubuntu 系 apt-get install -y build-essential perl # RHEL / CentOS / 麒麟 / UOS 系 yum install -y gcc gcc-c++ make perl

perl是必须的,Run脚本本身是 Perl 写的,结果汇总也靠它。build-essential/gcc-c++里包含的makegcc就够编主体部分。

真正容易卡住的是图形测试。UnixBench 里带了两个基于 X11 的 2D/3D 图形测试,编译时需要libX11-dev(Debian 系)或libX11-devel(RHEL 系)。如果你没装这个开发包,make会在编译pgms/gfx-x11时报一堆找不到X11/Xlib.h的错误然后中断——注意是中断,前面编好的pgms/dhry2pgms/pipe这些还在,但整体make返回非零,很容易让人误以为全盘失败。

2.2 GCC 10 之后的 multiple definition 报错

这是最经典的一个坑,报错长这样:

/usr/bin/ld: dhry_1.o:(.bss+0x0): multiple definition of `_1_' /usr/bin/ld: dhry_2.o:(.bss+0x0): first defined here /usr/bin/ld: dhry_1.o:(.bss+0x8): multiple definition of `Too_Small_Time' collect2: error: ld returned 1 exit status

根因是 GCC 10 起把-fno-common变成了默认行为。以前 C 语言里在头文件写int _1_;这种"试探性定义",多个编译单元链接时会自动合并成一份;现在默认不允许,直接判定为重复定义。UnixBench 的dhry_1.cdhry_2.c就是这么写的,年代久远,正好踩在新默认值上。

解决办法有三种,我推荐第一种:

# 方案一:把 -fcommon 加回编译选项 sed -i 's/^CFLAGS = /CFLAGS = -fcommon /' Makefile make
# 方案二:环境变量方式(Makefile 里变量名可能是 CFLAGS 也可能是 COPTS,先 grep 一下) grep -n "CFLAGS\|COPTS" Makefile CFLAGS="-Wall -fcommon" make

方案三是直接改源码,把dhry_1.cdhry_2.c里那几个重复定义挪到单一.c文件,用extern声明。能改对,但改动量大、容易出新问题,不划算。

提示:如果你用的是较老的 GCC 9 及以前版本,这个报错不会出现。但我不建议为了跑分特意降 GCC 版本,因为 Dhrystone 的分数跟编译器版本强绑定,降版本会让你的数据跟别人对不上。

2.3 关掉图形测试的正确姿势

如果这台机器没有 X11 环境(服务器上基本都没有),有两个办法避开图形测试:

第一种,在 Makefile 里把图形测试开关关掉。找到GRAPHICS_TESTS那一行,把它置空或者改成false,再make。这样根本不会去编pgms/gfx-x11

第二种更省事:先装libX11-dev让它编过,编完之后把pgms/gfx-x11那个可执行文件删掉。Run脚本是靠检测这个二进制是否存在来决定跑不跑图形项的,文件不在,它就安静跳过。

我一般用第二种,因为第一种要改 Makefile,而 Makefile 我希望能保持原样存档,方便日后比对。图形测试本身对服务器评估也没什么价值——它主要压 X11 的绘图路径,跟后端服务性能几乎不相关。

2.4 编译完先核对产物

make返回 0 不代表万事大吉,一定要看一眼pgms/目录里该有的二进制齐不齐:

ls -1 pgms/ | grep -v "\." | sort

正常情况下你应该看到arithohcontext1dhry2dhry22execlfsbufferfsdiskfstimepipespawnsyscallwhetstone-doublemulti.sh这些。少任何一个,对应的测试项在Run时会被静默跳过,报告里就少一行——而几何平均的分母变了,你的系统指数就没法跟别人比。

3. 把变量摁住:跑分前的系统调优与观测

编译过了,接下来是最容易糊弄也最影响结果的一步。UnixBench 的设计目标是"测机器",但机器跑在操作系统上,操作系统的默认配置是为通用场景服务的,不是为跑分服务的。下面这几项调完,同一台机器重复跑分的波动能从 10% 收窄到 3% 以内。

3.1 频率策略、C-State 与 NUMA 放置

默认的ondemandschedutil调频策略会根据负载动态升降频。UnixBench 的每个子项只跑几十秒,前期还在升频爬坡,测出来的数就偏低。跑之前把它钉死:

for g in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance > "$g" done cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

如果这台机器上找不到cpufreq目录,可能是 BIOS 里把 P-State 关了、或者用了acpi-cpufreq之外的管理方式,可以用cpupower frequency-info确认当前状态。再顺手跑一下grep MHz /proc/cpuinfo,看各核是不是都顶在最高频。

C-State 方面,深度睡眠状态会让核从空闲唤醒时有一段延迟,对 Execl、Process Creation、Context Switching 这几项影响明显。有条件的话在 BIOS 里把 C6 之类关掉,或者内核启动加processor.max_cstate=1。生产机当然不建议这么干,跑分机上无所谓。

NUMA 放置这件事,跑单副本和跑多副本的策略应该分开:单副本时把进程绑到 node 0,让它吃本地内存,测的是单核峰值;多副本时用numactl --interleave=all,让内存页均摊到四个节点,测的是整机吞吐。这两种配置测出来的东西不一样,别混着比。

3.2 文件系统与内存:文件拷贝类测试的真正瓶颈

File Copy 那三项,我在不少报告里看到被当成磁盘性能来解读,这是彻头彻尾的误解。它的工作方式是在 UnixBench 目录下建一个固定大小的文件反复读写,文件大小远小于内存,所以数据几乎全在页缓存里打转。它实际测的是:

  • 内存子系统的拷贝带宽(跟通道数、频率直接相关)
  • 页缓存的查找与管理效率
  • 拷贝时用的缓冲区大小对 cacheline 利用率的匹配程度

所以在容器里跑 UnixBench,如果工作目录落在 overlayfs 上,File Copy 分数会莫名其妙掉一大截——overlayfs 的写时复制路径比原生文件系统重得多。我的做法是把 UnixBench 解压到宿主机的本地分区(ext4 或 XFS),并且记录当时的挂载参数:

df -T /opt/UnixBench mount | grep -E "$(df --output=source /opt/UnixBench | tail -1)"

另外,透明大页(THP)对这类内存密集型测试的影响也不小。默认madvise模式下,大部分进程拿不到大页;切到always会让 File Copy 和 Pipe 的分数有可见提升。我习惯在跑分前把它固定成一种状态并记录在案,而不是任由它跟随系统默认值漂移。

3.3 用 taskset 和 numactl 把负载钉在固定位置

多副本跑分时,如果让调度器自由发挥,进程可能被扔到任意 NUMA 节点上,跨节点访存的比例每次都不一样,结果自然飘。用taskset限定物理核范围、用numactl限定内存策略,能显著改善重复性:

# 单副本,只允许在 node 0 的核上跑,内存走本地 numactl --cpunodebind=0 --membind=0 ./Run -c 1 -i 3 -q # 32 并发,全机核都用,内存交错分布 numactl --interleave=all taskset -c 0-31 ./Run -c 32 -i 3 -q

有一点要注意:taskset -c 0-31里的 0-31 是逻辑 CPU 编号。在开了 SMT 的机器上,相邻编号往往是同一个物理核的两个线程。想只占物理核,得先查/sys/devices/system/cpu/cpu*/topology/thread_siblings_list把物理核编号列出来。我这次跑-c 32就是想看 32 个物理核的满配表现,所以直接用了 0-31,接受一个核上可能有两个线程的情况——但我会在报告里写清楚这个前提。

3.4 一套我固定使用的执行命令模板

把所有前置动作串起来,我用的脚本大概长这样,你可以直接抄:

#!/bin/bash set -euo pipefail UB=/opt/UnixBench STAMP=$(date +%Y%m%d_%H%M%S) OUT=$UB/results/$STAMP mkdir -p "$OUT" cd "$UB" # 1. 固定调频策略 for g in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance > "$g" 2>/dev/null || true done # 2. 快照环境信息 { echo "=== lscpu ==="; lscpu echo "=== numactl -H ==="; numactl -H echo "=== governor ==="; cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null echo "=== kernel ==="; uname -a echo "=== mount ==="; df -T "$UB" echo "=== load ==="; uptime } > "$OUT/env.txt" 2>&1 # 3. 空载确认 sleep 60 uptime > "$OUT/load_before.txt" # 4. 单副本 numactl --cpunodebind=0 --membind=0 ./Run -c 1 -i 3 -q > "$OUT/run_c1.log" 2>&1 # 5. 32 并发 numactl --interleave=all ./Run -c 32 -i 3 -q > "$OUT/run_c32.log" 2>&1 echo "done: $OUT"

-i 3表示每个子项跑三轮,Run会把三轮结果取平均后再算 Index,比跑一轮的结果重复性好得多。代价是总耗时翻三倍,全流程大概要四十分钟到一个小时,建议放在运维窗口里跑。

4. 实测数据拆解:单副本、32 并发与扩展比

数据这部分我先说清楚性质:下面这组数字是我在这台 C86 7280 上一次完整实测的参考值,用来演示"怎么读数",不是权威的横向评测结论。你的机器因为 BIOS 版本、内存插法、内核版本、编译器的差异,数字一定会有出入,重要的是分析思路。

4.1 单副本:11 项分值与总指数怎么算出来

./Run -c 1 -i 3 -q跑完之后,整理出来的分项如下:

子项本次结果基准值Index
Dhrystone 2 using register variables42,000,000 lps116700.03598.9
Double-Precision Whetstone4,900 MWIPS55.0890.9
Execl Throughput3,900 lps43.0907.0
File Copy 1024 bufsize 20001,180,000 KBps3960.02980.0
File Copy 256 bufsize 500430,000 KBps1655.02598.2
File Copy 4096 bufsize 80004,200,000 KBps5800.07241.4
Pipe Throughput1,320,000 lps12440.01061.1
Pipe-based Context Switching185,000 lps4000.0462.5
Process Creation9,200 lps126.0730.2
Shell Scripts (1 concurrent)5,100 lpm42.41202.8
System Call Overhead12,500,000 lps15000.08333.3

系统指数不是算术平均,是几何平均。手算容易出错,我一般直接用一段 Python 核一遍:

import math idx = [3598.9, 890.9, 907.0, 2980.0, 2598.2, 7241.4, 1061.1, 462.5, 730.2, 1202.8, 8333.3] single = math.exp(sum(math.log(x) for x in idx) / len(idx)) print(f"项数={len(idx)} 单副本系统指数={single:.1f}") # 项数=11 单副本系统指数=1785.6

这个 1785 就是单副本的系统指数,可以理解成"平均比 1990 年代的 SPARCstation 20-61 快 178 倍"。

几个值得注意的点:System Call Overhead的 Index 冲到了 8333,这是因为它本身基准值低而现代 CPU 的getpid成本极低;但如果你这台机器开了全套内核漏洞缓解,或者内核版本比较新、加了额外的安全钩子,这项可能直接腰斩到 4000 以下,进而把整个系统指数拉低十几个百分点。Pipe-based Context Switching的 462 是单副本里最低的一项,说明上下文切换是这台机器单核路径上相对薄弱的一环,后面调优要盯着它。

4.2 32 并发:报告为什么多了一条 Shell Scripts

./Run -c 32 -i 3 -q的结果:

子项本次结果基准值Index
Dhrystone 2 using register variables900,000,000 lps116700.077121.7
Double-Precision Whetstone105,000 MWIPS55.019090.9
Execl Throughput72,000 lps43.016744.2
File Copy 1024 bufsize 20004,800,000 KBps3960.012121.2
File Copy 256 bufsize 5001,150,000 KBps1655.06948.6
File Copy 4096 bufsize 800012,500,000 KBps5800.021551.7
Pipe Throughput11,500,000 lps12440.09244.4
Pipe-based Context Switching950,000 lps4000.02375.0
Process Creation32,000 lps126.02539.7
Shell Scripts (1 concurrent)2,800 lpm42.4660.4
Shell Scripts (8 concurrent)14,000 lpm6.023333.3
System Call Overhead45,000,000 lps15000.030000.0

12 项,几何平均:

import math idx = [77121.7, 19090.9, 16744.2, 12121.2, 6948.6, 21551.7, 9244.4, 2375.0, 2539.7, 660.4, 23333.3, 30000.0] multi = math.exp(sum(math.log(x) for x in idx) / len(idx)) print(f"项数={len(idx)} 32并发系统指数={multi:.1f}") # 项数=12 32并发系统指数=10138.2

系统指数落在 10100 附近。这个数字好不好?没有对照机就答不了这个问题。但内部结构一眼就能看出门道,下一节拆。

4.3 扩展比拆解:谁的锅,谁的表现正常

把两张表并排算一下倍数,问题立刻显形:

子项单副本 Index32 并发 Index扩展倍数
Dhrystone 23598.977121.721.4x
Double-Precision Whetstone890.919090.921.4x
Execl Throughput907.016744.218.5x
File Copy 10242980.012121.24.1x
File Copy 2562598.26948.62.7x
File Copy 40967241.421551.73.0x
Pipe Throughput1061.19244.48.7x
Pipe-based Context Switching462.52375.05.1x
Process Creation730.22540.03.5x
Shell Scripts (1 concurrent)1202.8660.40.55x
System Call Overhead8333.330000.03.6x

从这张表能读出三层信息:

第一层,纯计算类(Dhrystone、Whetstone)扩展比 21.4x,32 核拿到 21 倍,效率 67%。剩下的损耗来自内存带宽争抢、共享 L3 争用、以及 SMT 对整数负载帮助有限。这个水平在 32 核机器上属于正常偏上。

第二层,内核路径类(Process Creation 3.5x、Context Switching 5.1x、Syscall 3.6x)扩展比集体趴窝。这不是这台机器的缺陷,几乎所有多核平台在这几项上都是个位数扩展——fork涉及页表复制、调度器要抢运行队列锁、内核里几个热点结构存在共享竞争。跑到 3 到 5 倍已经是比较健康的数值。

第三层,也是最有意思的一层:Shell Scripts (1 concurrent)从 1202 掉到 660,扩展比 0.55x——并发跑的时候它反而变慢了。原因很直白:32 个 UnixBench 副本同时在跑,每个副本内部都要 fork shell 进程,全机进程创建压力巨大,而这一项测的恰恰是"在有多重进程创建压力的情况下,完成一次 shell 脚本执行要多久"。它慢下来,反而说明这台机器在重进程压力下还能保持吞吐,只是单个请求的延迟被拉长了。

提示:看到某个子项的并发扩展比小于 1,先别急着喊"有问题"。要区分清楚是资源竞争导致的延迟增加,还是真的出现了锁死或者饿死。判断方法是看全机 CPU 利用率——如果跑分期间mpstat -P ALL 1显示所有核都接近满载,那就是竞争,不是故障。

5. 从结果里读出问题:几个典型异常与排查路径

跑分最大的价值不在那一个总指数,而在于它能帮你定位"这台机器到底哪条通路偏弱"。下面这几个是我在实际工作中反复遇到的异常形态,以及对应的排查链路。

5.1 文件拷贝分数忽高忽低,八成不是磁盘慢

File Copy 三项在重复跑分时波动比较大,尤其是 File Copy 256 这一项,因为它用的缓冲区最小,对页缓存行为和 CPU cache 命中率最敏感。如果你的波动超过 15%,按这个顺序排查:

  1. 工作目录落在哪df -T看文件系统类型,overlayfs、fuse、网络文件系统都会显著拖慢。换到原生 ext4/XFS 的本地分区再跑。
  2. 有没有别的进程在吃内存带宽。我用perf stat -e LLC-loads,LLC-load-misses -a sleep 30在跑分期间采一段,看 LLC 未命中率是不是异常高。
  3. NUMA 策略对不对。如果 32 个副本均匀分布在四个节点上,但每个副本只在一个节点上读内存,远端访问比例会随调度漂移。固定--interleave=all能让这个变量消失。
  4. THP 状态。切换/sys/kernel/mm/transparent_hugepage/enabled的值,对比两次结果,差异超过 5% 就说明它是主要变量。

顺带说一句,很多云主机上跑的"UnixBench 跑分"之所以 File Copy 分数特别好看,是因为它们的文件系统铺在内存盘上。这种分数在服务器评估里没什么参考价值,看报告时一定要问清楚存储介质。

5.2 进程创建与上下文切换:内核路径上的天花板

这两个子项是整机扩展性的"照妖镜"。当一台机器的 Process Creation 扩展比低于 3x,基本可以判定瓶颈在下面这几处之一:

  • 内核版本的调度器实现。较新的内核在进程创建路径上做了不少优化,比如fork时对页表的懒拷贝、运行队列锁的细分。同一硬件,内核从 4.19 升到 5.10 以上,这项普遍有 20% 到 40% 的提升。
  • 安全缓解措施。各类漏洞缓解补丁会给系统调用和上下文切换加额外开销。可以通过对比/sys/devices/system/cpu/vulnerabilities/下各条目的状态来确认,全部为Not affected和全部为Mitigation的机器,Syscall 分数能差出一倍。
  • fork之外的因素。这台机器上有大批服务在后台跑(监控、日志、审计),它们本身就在不停创建进程,会给跑分带来噪声。跑分前的静默期必须做足。

我的一般做法是:拿 Process Creation 的绝对值跟同代、同核数机器比,只要落在合理区间(32 核在 25000 到 40000 lps 之间),就不深究;低于 20000 才值得查内核参数。

5.3 并发上不去,先查这三处

如果你发现 32 并发的系统指数跟 16 并发比几乎没有提升,别怀疑 UnixBench 脚本,按下面三处查:

第一处,SMT 是不是没有被正确利用-c 32如果被taskset绑到同一批物理核上,等于把负载压在半数核心上。用lscpu -e看清楚 CPU 编号和核心的对应关系,确认你的核范围覆盖全机。

第二处,内存带宽是不是已经打满。File Copy 这类测试在 32 并发时会逼近内存带宽上限,此时加核只会加剧争抢。跑分期间用pcm-memory或者perf stat -e uncore_imc_0/cas_count_read/看内存控制器的读数,如果接近理论峰值的 80% 以上,说明带宽见顶了。

第三处,共享缓存争用。32 个进程共享 64MB L3,每个进程分到 2MB。Dhrystone 这类工作集小的测试矛盾不大,但 File Copy 4096 这种工作集大的会频繁抖动。可以试一次-c 16,如果 16 并发的系统指数乘 2 反而超过 32 并发的系统指数,就说明已经过了规模收益拐点。

5.4 同一配置跑三次,差多少才算正常

这部分是我踩坑最多的地方。早期我做对照测试,经常拿两个只差 5% 的分数下结论,后来发现同一台机器同一配置连跑三次,系统指数的波动本身就有 3% 到 5%。

我现在的判断标准是:

波动幅度判断
系统指数差异 < 3%视为一致,不做结论
系统指数差异 3% ~ 8%需要排查环境变量,确认调频、NUMA、后台负载是否一致
系统指数差异 > 8%结果不可用,重跑并逐项比对原始 log
单个子项(Syscall、Context Switch)差异 > 15%属于正常范围,这两项天生噪声大

有个小技巧:不要只看汇总的系统指数,一定要保留原始的results/*.log。我在排查一次 7% 的抖动时,就是靠在两轮 log 里逐行比对,发现只有 Process Creation 这一项差得特别多,最后定位到是系统的定时任务在那几分钟起了几个进程。

6. 让分数有意义:UnixBench 的正确用法与其他工具的配合

跑出一堆数字不算本事,让这些数字在决策里发挥作用才算。这一节说几个我认为最重要的使用原则,以及 UnixBench 在和别的工具配合时的位置。

6.1 让分数可比:版本、对照机、参数三件套

UnixBench 的分数在互联网上被引用太随意了。我见到过拿-c 1的分数去跟别人-c 64的分数作对比,也见到过拿 5.1.3 的分数跟某个魔改版的分数比。任何一次有效的对比,必须同时具备三个要素:

  1. 完整的版本标识。不只是"UnixBench 5.1.3",而是源码包的来源加上 commit hash。我在报告里会写byte-unixbench @ <hash>这种形式。
  2. 对照组。没有对照机的绝对分数只能作为存档记录,不能作为结论。要评估 C86 7280 的水平,必须用另一台已知性能的机器,用完全相同的编译产物、完全相同的参数跑一遍。
  3. 完整参数记录-c多少、-i多少、NUMA 策略、调频策略、内核版本、文件系统类型、内存配置,一个都不能少。我习惯把这些塞进一张环境快照表,跟分数一起存档。

另外提醒一句:跨架构之间比 UnixBench 意义不大。x86 和 ARM 在这套测试上的子项权重分配是历史形成的,对 x86 更友好。要做跨架构评估,应该用更现代的、向量化和内存访问更均衡的工具。

6.2 UnixBench 之后该接什么:应用压测的分工

我在实际项目里的测试分层大致是这样:

层次工具回答的问题
系统底座UnixBenchCPU 整数浮点、进程、管道、文件、系统调用的原始能力
子系统sysbench(CPU/内存/线程/互斥锁)更细粒度的定点数、内存延迟与带宽、线程调度
IOfio、iperf3存储 IOPS/带宽/延迟、网络吞吐
应用层JMeter、LoadRunner业务接口在并发用户下的响应时间与吞吐

UnixBench 是第一层。它的结论通常是"这台机器的 CPU 通路够用,但进程创建路径偏弱"或者"内存带宽充足,单核浮点偏弱"。这种结论本身不能直接回答"能支持多少并发用户",但能给你一个排查的坐标系。

真正到业务评估阶段,就得换成 JMeter,写测试计划、配线程组、设 ramp-up、加断言和监听器,跑完拿到 TPS、P95、错误率。如果组织里用的是 LoadRunner,流程上大同小异:录制或手写脚本、设计场景、设置集合点、跑场景、分析报告。这两类工具做的是应用层压测,它们的测试方案必须把机器底座的能力作为前置输入——否则你会遇到一个很尴尬的局面:压测压不上去,你花了两周调应用参数,最后发现是机器在进程创建路径上已经到顶了,这个信息其实第一天的 UnixBench 报告里就写着。

我的建议是,性能测试方案里中央处理器的底座测试应该放在最前面,时间成本只有一两个小时,但能帮你省掉后面几周的错误方向。JMeter 测试步骤再细,也是在应用层打转,它看不到内核进出成本;LoadRunner 测试步骤再规范,也测不出内存带宽是不是已经打满。两者是互补关系,不是替代关系。

6.3 我自己固定下来的几条测试纪律

最后分享几条我在长期做这类测试时固定下来的习惯,每一条都是被坑出来的:

  • 环境快照必须先落盘再跑分lscpunumactl -Huname -adf -Tfree -h、调频策略,全部写进一个env.txt。事后出问题时,你唯一能依赖的就是这份快照。
  • 一次只改一个变量。想测 THP 的影响就只改 THP,不要在同时换内核版本的情况下比较。我吃过一次教训:同时换了内核和 GCC 版本,结果分数涨了 12%,完全不知道为什么涨。
  • 原始 log 保留至少半年。汇总表格只留分数,一旦有人质疑某个数字,你没法自证。保留原始 log,随时能翻出每一轮的完整输出。
  • 不要在跑分机上装监控 agent。很多监控 agent 是秒级采集,正常运行时占用很小,但它们会在跑分期间产生周期性的系统调用和进程创建,恰好干扰 Execl 和 Process Creation 这两项。要监控就用外部的 IPMI 或者带外接口。
  • 跑分前留出十分钟静默期。让系统把积压的日志刷盘、把定时任务跑完、把缓存预热。十分钟成本很低,但能让重复性好上一个台阶。

这台 C86 7280 最后的结果是:单副本系统指数 1785,32 并发系统指数 10100 左右,整数和浮点通路的扩展性在预期之内,进程创建和上下文切换受内核路径限制属于正常水平。对我们要跑的那套后端服务来说,这个底座是够的,真正的瓶颈会出现在应用层而不是硬件层。后来我们按这套结论把 JMeter 压测方案定下来,整个调优周期比上一个项目短了差不多三周,省下来的时间基本都是靠这台机器第一天跑出来的那份分项清单。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 1:40:30

传感器阵列波束优化:物理建模与MATLAB约束求解

简介&#xff1a;本资源是面向嵌入式系统、物联网及信号处理方向学习者与工程师的MATLAB实践代码包&#xff0c;聚焦传感器阵列波束优化设计核心算法实现&#xff0c;解决实际工程中主瓣控制、旁瓣抑制、信噪比提升与多目标定向跟踪等关键问题。压缩包共75个文件&#xff0c;主…

作者头像 李华
网站建设 2026/9/17 1:40:25

钉钉工作通知消息API开发实战:从access_token到消息撤回全指南

最近因为要给运维告警加一套消息推送&#xff0c;我把钉钉服务端API里工作通知消息这套接口完整过了一遍。这套接口的应用价值其实很大&#xff1a;企业内部系统需要把告警、审批、待办这类关键信息实时推给指定员工&#xff0c;工作通知消息是官方提供的标准通道&#xff0c;相…

作者头像 李华
网站建设 2026/9/17 1:40:01

职场可控混乱策略:低效背后的安全智慧

1. 效率悖论&#xff1a;为什么低效反而更安全&#xff1f;在职场中&#xff0c;我们常常被教导要追求高效、优化流程、提升产出。但有趣的是&#xff0c;在某些特定场景下&#xff0c;刻意保持一定程度的低效反而能带来意想不到的职业安全感。这种现象被称为"可控混乱&qu…

作者头像 李华
网站建设 2026/9/17 1:39:48

HiL测试工程师入门:CANoe环境构建与CAPL工程化实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华