尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

lmbench3 微基准测试套件安装实战与性能指标解读

lmbench3 微基准测试套件安装实战与性能指标解读 如果你做过Linux服务器的性能评估一定对fio、iperf3、unixbench这些名字不陌生但真正要把一台机器的“底子”摸清楚时我总会翻出上世纪九十年代出生的lmbench3。这套微基准测试套件虽然年纪大却能一次性覆盖内存带宽、内存延迟、上下文切换、进程创建、文件系统操作、TCP/UDP延迟等几十个维度而且体积小、部署快特别适合做系统级横向对比。不过它毕竟是一套老代码在现代Linux发行版上安装、使用时会遇到不少坑网上资料又比较零碎。这篇文章就结合我自己的实测经验把lmbench3的安装、使用、常见问题和结果解读一次性说清楚适合运维、性能测试工程师以及想深入了解自己机器底层能力的开发同学。1. lmbench3是什么为什么现在还在用它1.1 它到底能测什么lmbench3是一套可移植的微基准测试工具集最早由Sun Microsystems的Carl Staelin等人开发目标是对系统硬件、操作系统以及应用程序的基础能力做细粒度测量。它测的核心项目可以分成两大类带宽Bandwidth和延迟Latency。带宽类测试包括内存拷贝带宽bw_mem、管道带宽bw_pipe、TCP带宽bw_tcp、UDP带宽bw_udp、Unix socket带宽、文件读取带宽等。延迟类测试更有意思包括内存读延迟lat_mem_rd、上下文切换耗时lat_ctx、进程创建与退出耗时lat_proc、系统调用耗时lat_syscall、信号处理开销、文件系统创建与删除延迟lat_fs、TCP连接建立延迟、UDP往返延迟、页面缺失处理耗时等。我最早用lmbench3是想对比两台看起来“配置差不多”的服务器为什么跑业务时差异明显。当时用fio和iperf3分别看磁盘和网络发现两者都很正常后来跑了一轮lmbench3发现其中一台的内存延迟比另一台高了将近一倍再查下去是BIOS里NUMA节点交错策略没开导致跨节点访问频繁。这个结论用其他工具很难快速得出来。1.2 相比现代测试工具它的独特价值很多人问为什么不用perf、strace或者更现代的benchmark工具这些工具当然有用但定位不太一样。perf更像是一个“探针”适合去深入分析某一个具体瓶颈而对多维度底层基线数据厂家往往愿意给一个统一可比的分数。lmbench3的优势在于三点第一覆盖维度足够全一套工具能同时拿到几十个基础性能指标省得在多个工具之间来回切换。第二体积小、依赖少编译出来不到几MB可以轻松丢到各种老旧服务器或嵌入式环境里跑。第三可移植性好它能跑在Linux、BSD、Solaris、AIX甚至一些古老的Unix系统上横向对比不同操作系统版本时非常方便。当然它也有明显短板比如没有图形界面、结果展示比较原始、部分微基准在现代CPU和内核上测得的值需要小心解读。所以我的建议是lmbench3适合做系统级基线评估和横向对比不适合用来指导某一个具体应用的参数调优。真要看业务体感还是需要配合fio、iperf3、perf这类工具一起用。2. 安装从下载到编译通过的正确姿势2.1 环境准备与下载lmbench3现在最常见的发行版本是3.0-a9网上流传的压缩包名称一般是lmbench-3.0-a9.tar.gz。由于原站点年代久远直接访问不一定稳定建议去GitHub搜索“lmbench”找3.0-a9版本的镜像仓库下载。无论从哪下载解压后目录结构基本一致核心代码都在src子目录里。在开始之前请先确认系统装好了基础编译工具链。Debian/Ubuntu系执行sudo apt-get install -y build-essential m4RHEL/CentOS系执行sudo yum groupinstall -y Development Tools sudo yum install -y m4除了gcc和make最容易被忽略的是m4。lmbench的构建过程会用到它来生成部分配置头文件如果系统里没有m4编译阶段会报一些比较诡异的错误比如找不到某些头文件这时候完全想不到是m4缺失导致的。2.2 编译前的关键配置进入解压后的目录切换到srccd lmbench-3.0-a9/src make直接执行make时构建脚本会自动探测当前操作系统并生成对应的配置。在大部分主流发行版上这一步能顺利通过。如果提示unknown OS或无法识别系统类型可以手动指定操作系统类型比如make OSlinux这个操作的本质是告诉构建系统去加载src/scripts/Makefile.linux之类的配置文件。不同发行版可能标识不同通常试linux就能解决。如果机器上没有root权限编译本身不影响但后续跑测试时很多项目会因权限不足而失败后面会单独讲。建议在有root权限的环境下编译和测试。2.3 编译过程与踩坑实录我用的测试机是Ubuntu 22.04gcc版本12编译时遇到了一个典型问题报错implicit declaration of function getpagesize。原因是lmbench3的年代太早源码里很多头文件没有显式声明_GNU_SOURCE而新版本glibc把一些接口的隐式声明收紧导致gcc在编译时直接抛出warning甚至error。解决办法很简单在src/Makefile里找到CFLAGS相关行把默认的-O2改成-O2 -D_GNU_SOURCE或者用命令行传递make CFLAGS-O2 -D_GNU_SOURCE我的经验是直接改src/Makefile更省事因为后续每次保存配置、重新编译都会自动带上这个宏避免重复传参。如果没改Makefile只靠命令行传参某些子模块在单独编译时可能会漏掉CFLAGS又回到报错原样。另外在gcc 13以上版本编译时还可能遇到implicit declaration相关的waring被升级为error的情况。如果不想逐个头文件去补声明可以在CFLAGS里追加-Wno-implicit-function-declaration把这类提示降级为警告让编译继续往下走。这个参数不影响生成的二进制功能只是用来绕过老代码与现代编译器之间的小摩擦。编译成功后src目录下会生成一批带的时间戳的可执行文件比如bw_mem、lat_mem_rd、lat_ctx、lat_proc、lat_fs、lat_tcp等。在决定跑全量测试之前建议先单独运行几个小命令验证一下比如./bw_mem 64m rd如果这条命令能正常输出带宽数据说明编译产物基本可用。3. 使用跑一次完整基准并看懂结果3.1 交互式跑测与自动化跑测完整跑一遍lmbench3有两种方式一是在src目录里执行make results它会连带执行配置、编译、测试、汇总等一整套流程适合全量评估二是单独执行src下的各个测试程序适合只关心某几个指标。make results这套流程是交互式的运行期间会问不少问题比如测试结果保存到哪个目录、文件系统测试的最小目录大小设多少、是否允许在NFS等网络文件系统上测试等等。第一次跑的时候大部分人看到一连串提问都会有点懵我的建议是除了“是否允许网络文件系统测试”按需选择外其余都直接回车接受默认值。它给出的默认值在绝大多数服务器上都是合理的后期也完全可以改。由于全量跑测时间较长一般在几十分钟到几个小时不等强烈建议放到tmux或screen会话里执行防止SSH断开导致工作前功尽弃。我第一次跑的时候没注意直接挂在SSH终端里中间网络闪断一次整个测试过程全部白费后来学乖了所有耗时任务一律先进tmux。如果想自动化跑测可以把交互输入通过管道喂进去。比如yes | make results这个命令会把默认回答一路回车下去。如果你的场景需要自定义某几个参数可以分步执行先make config生成配置文件再修改results里的配置文件最后再执行make results。这样比纯交互式可控性高很多。3.2 核心测试项速查与常用参数单独执行某个测试程序时先cd src然后运行对应命令。我整理了一套日常最常用的组合测试目标命令示例说明内存读延迟./lat_mem_rd -P 1 128M 512测128MB数组在不同步长下的读取延迟内存拷贝带宽./bw_mem -P 1 128M cp测128MB内存拷贝带宽内存读写带宽./bw_mem -P 1 128M rd测128MB内存读带宽上下文切换./lat_ctx -P 1 -s 64 2 4 8 16 24 32 64 96 128测不同进程数量下的上下文切换延迟进程创建延迟./lat_proc fork测forkwait流程耗时进程创建执行延迟./lat_proc exec测forkexecwait流程耗时文件创建删除延迟./lat_fs /tmp在指定目录测文件创建和删除耗时TCP连接延迟./lat_tcp -P 1 127.0.0.1测本机TCP连接建立耗时UDP延迟./lat_udp -P 1 127.0.0.1测本机UDP通信延迟系统调用延迟./lat_syscall open测open系统调用耗时这里重点说两个高频使用的参数。-P表示并行进程数如果只看单线程性能建议固定为1-N表示测试重复次数一般默认足够。对lat_mem_rd来说第一个数字是数组大小第二个数字是最大步长。数组大小要明显大于内存总量的一半才能保证访问真正落到内存而不是被缓存兜住步长则是为了模拟随机访问模式通常取128到512之间即可。跑完以后屏幕会直接输出结果比如lat_mem_rd的输出会是一个二维序列左边是数组大小右边是对应的延迟时间。如果只想做快速对比可以直接把这些数字记下来但更标准的做法是看汇总文件。3.3 结果文件怎么读、怎么对比执行make results后结果会被写入results目录下的子目录中子目录名通常与机器名和系统标识相关。每个子目录里包含多个单独结果文件以及一个汇总文件。你可以用make see直接查看汇总也可以进到对应目录下cat汇总文件。汇总文件里的核心内容分为两块一块是机器基本信息包括CPU频率、操作系统版本、编译参数等另一块是各项基准测试的最终数值。对比两台机器时我的习惯是并排打开两份汇总文件先看机器基本信息确认两者是否处于同等的配置状态比如CPU是否都锁定在性能模式、内存是否都开启了同样的NUMA策略然后再看指标数据。这里有一个很关键的经验不要只对比平均分要看单指标分布。例如lat_mem_rd的输出里数组大小从1KB增长到128MB的过程中延迟会呈现阶梯式上升。每一段“台阶”分别对应L1 Cache、L2 Cache、L3 Cache和内存。如果你发现两台服务器的L3 Cache延迟有明显差异那问题很可能出在CPU型号或固件配置上而不是操作系统层面。4. 常见问题与排查技巧实录4.1 编译阶段典型报错速查表我整理了在编译lmbench3时最常碰到的几类报错和解决方案报错信息原因分析解决办法implicit declaration of function getpagesize老代码缺少_GNU_SOURCE声明新glibc收紧隐式声明CFLAGS加-D_GNU_SOURCE各种implicit declaration被当errorgcc新版默认将隐式声明视为错误CFLAGS加-Wno-implicit-function-declarationm4: command not found缺少m4宏处理器安装m4unknown OS或系统类型无法识别构建脚本无法自动匹配当前系统手动指定make OSlinux提示权限不足无法编译/运行部分场景需要写系统目录使用root或编译安装到用户目录有朋友问过能不能不做任何修改、直接编译安装在较老的操作系统上确实可以但在2024年以后发布的Linux发行版上完全不改动就一次性通过的几率比较低。不要怕改CFLAGS这属于正常操作。4.2 运行阶段权限、容器、网络干扰编译通过后运行阶段还会遇到一些问题。最常见的是权限类报错。lmbench的部分测试会尝试调整进程优先级、设置实时调度策略这些操作需要root权限。如果当前用户不是root运行时会提示无法设置调度器或类似信息。我的建议是统一加sudo运行尤其是make results这种全量测试否则某些项目会静默跳过或得到错误数据。在容器环境中这个问题会更明显。Docker容器默认对进程的能力做了裁剪即使容器内root用户也可能没有CAP_SYS_NICE之类的权限导致无法完成实时调度相关测试。解决办法是启动容器时加上--privileged参数或者至少加上--cap-addSYS_NICE。但我个人观点是如果你要做严谨的CPU性能测试尽量不要在容器里跑虚拟化层和共享内核会引入额外干扰测试出来的数字跟宿主机直接跑会有偏差。容器适合验证工具流程是否通顺不适合用来出正式数据。网络相关测试也容易踩坑。比如测lat_tcp、bw_tcp时如果机器上开着防火墙延迟和带宽数字都会变得非常难看。解决办法是先把防火墙策略放行对应端口或者使用回环地址测试本机协议栈性能。还有一点云主机如果开启了安全组或流量限速策略默认的测试数据往往不是实例性能的真实反映。要区分本机协议栈和网络链路两件事最好的办法是先测127.0.0.1再测另一个内网IP两者对比就能大致判断干扰来自哪个环节。4.3 结果异常怎么排查有时候测试结果跟预期相差很大不要急着怀疑机器坏了先用下面几步排查。第一检查CPU频率是否稳定。现代处理器都有动态调频机制如果CPU governor处于powersave模式算出来的内存带宽和延迟数据会严重偏低。测试前建议把cpu调到performance模式cpupower frequency-set -g performance或者手动将/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor设置为performance。这一步做完数据波动通常会明显下降。第二检查后台负载。跑测时如果有其他业务进程在抢占CPU、内存或磁盘IO结果自然会乱。测试前至少保证系统空闲关闭不必要的服务尤其要停掉cron定时任务和数据备份任务。我遇到过不止一次白天跑lmbench3数据忽高忽低晚上重跑就稳定了最后发现是监控agent定时采样导致的。第三关注NUMA影响。对多路服务器尤其是两路以上的机器内存访问可能跨NUMA节点。如果lmbench的任务被调度到node 0但内存分配落在node 1延迟数据会高出一截。排查方法是用numactl --hardware查看节点拓扑再用numactl --cpunodebind0 --membind0锁定测试进程的内存亲和性。这样测出来的数据才具备可比性。第四重复测试取中位数。微基准测试天然存在一定抖动一次跑出来的数据不具备说服力。我的习惯是对关键指标至少跑三遍取中位数作为最终结论。而且不要只看平均值异常值往往能暴露问题比如某一次延迟突然飙高通常意味着测试过程中发生了调度抢占或中断干扰。5. 一点实操心得跑lmbench3这件事看起来简单但想拿到的是一份“能打到报告里、经得起推敲”的数据需要对测试环境有很强的控制力。我自己每次跑之前都会固定一套流程先查CPU governor再查NUMA策略关掉不必要的后台任务最后放在tmux里跑。没有这套固定动作结果是很难复现的。另外说一个容易被忽略的细节lmbench3的默认结果汇总里会有calibration相关数据这是工具自动校准计时器时产生的不用管它但如果在结果文件里看到某个测试项耗时过短比如小于1微秒要警惕它是否真的有效。这类微基准数据对时钟精度很敏感最好先跑一遍make results里的校准流程确认基准值正常再开始正式测试。最后再分享一个小技巧如果你只想快速比较两台机器不用傻傻跑完所有项目。先分别跑./bw_mem 128M cp、./lat_mem_rd -P 1 128M 512、./lat_ctx -P 1 -s 64 2 4 8 16 24 32 64这三条基本上CPU缓存、内存带宽、内存延迟和调度器能力都能反映出来。其余指标按需补充就行。这样一轮测下来10分钟之内就能拿到关键基线数据效率高很多。
返回列表