云服务器的CPU核数、磁盘IO这些参数大家看得很仔细,但内存带宽这个指标经常被忽略。实际上,虚拟机之间的内存性能差距可能非常大,同一份代码在两台标称配置相近的机器上跑出两倍的性能差异并不罕见,问题往往就出在内存子系统的吞吐能力上。Stream是一套专门测内存带宽的经典基准程序,由美国弗吉尼亚大学的John McCalpin博士开发,几十年来一直是HPC领域的标准测试工具,用它来评估云服务器的内存性能非常合适。

为什么内存带宽测试对云服务器特别重要
在物理机上,内存控制器直连CPU,性能基本由硬件决定,测试结果比较稳定。但云服务器是虚拟化环境,你的虚拟机可能与其他租户共享同一台物理宿主机,内存访问还要经过虚拟化层的调度。这就导致云主机的内存带宽不仅取决于CPU型号,还受到超售比例、邻居负载、NUMA调度策略等多重因素影响。
举一个典型的场景:你在做数据库压测,发现QPS始终上不去,CPU利用率却只有60%左右。这种情况下很可能就是内存带宽成了瓶颈,CPU在等数据而不是在算数据。Stream测试的价值就在于,它能在你正式部署业务之前,用一个标准化的数字告诉你这台云主机的内存子系统到底处于什么水平。
另外一个实际用途是横向比价。不同云厂商的同规格实例价格可能接近,但内存通道配置、是否绑核、是否独享物理机差异很大。跑一次Stream测试,几分钟就能看出谁在内存性能上更实在,这比看宣传页面上的参数靠谱得多。
Stream测试的原理和四种模式
Stream的核心思想很简单:构造一个远大于CPU缓存的数据集(默认约2GB),然后反复执行四种典型内存操作,统计单位时间内搬运的数据量。因为数据量远超三级缓存,CPU无法从缓存中命中数据,必须不断访问内存,测出来的就是真实的内存吞吐能力。
四种测试模式分别对应不同的访问模式。Copy是最基础的模式,执行a[i] = b[i],每次迭代读取8字节加写入8字节;Scale模式是a[i] = q * b[i],增加了一次乘法运算;Add模式是c[i] = a[i] + b[i],读取两个数组再写入一个;Triad模式是a[i] = b[i] + q * c[i],这是最接近科学计算真实负载的模式,也最能代表服务器的综合内存能力。
需要注意的是,Stream测的是持续带宽而不是峰值带宽。CPU规格书里写的那些漂亮的带宽数字通常是理论峰值,实际连续访问内存时能稳定达到的带宽往往只有峰值的七成左右,这也是为什么有些机器标称很高但实测一般的原因。
在Linux云主机上编译和运行Stream
Stream是一个单文件的C程序,官方提供源码下载,编译起来非常简单。登录云服务器后,先用wget获取源码,然后用gcc编译。关键点在于编译参数:必须加上-O3开启优化,并且要加-fopenmp启用OpenMP多线程支持,否则默认只跑单核,测出来的数字会低得离谱。
# 安装编译工具 yum install -y gcc wget # CentOS/RHEL # apt-get install -y gcc wget # Ubuntu/Debian # 下载Stream源码 cd /tmp wget https://www.cs.virginia.edu/stream/FTP/Code/stream.c # 编译,启用OpenMP并针对当前CPU架构优化 gcc -O3 -fopenmp -DSTREAM_ARRAY_SIZE=200000000 -DNTIMES=20 stream.c -o stream # 限制线程数等于物理核心数(超线程对带宽测试没有帮助) export OMP_NUM_THREADS=8 ./stream</code>
两个宏定义值得说明。STREAM_ARRAY_SIZE控制数组元素个数,每个元素8字节,默认值100000000对应约800MB数组。为了充分越过缓存,建议让数组总大小达到系统内存的4倍以上,比如32GB内存的机器可以设到200000000甚至更高。NTIMES是每种模式的执行次数,程序会取最优值,一般设20次就足够了。
如果你的机器是NUMA架构(云上的高配实例通常是),还可以用numactl把线程绑定到特定的NUMA节点,避免跨节点访问带来的带宽损失:
# 查看NUMA拓扑 lscpu | grep NUMA # 绑定到节点0运行,内存也在节点0上分配 numactl --cpunodebind=0 --membind=0 ./stream</code>
如何解读测试结果和排查异常数据
运行结束后会输出一个表格,每行是一种模式,重点看Rate (MB/s)这一列,也就是每秒搬运的兆字节数。一般流程是:先看Triad的数值,这是最常被引用的指标;再对比Scale和Add的数值是否合理,正常情况下四项结果的量级应该接近,Add和Triad通常会略高于Copy。以下是一台8核云主机的示例输出:
------------------------------------------------------------- Function Best Rate MB/s Avg time Min time Max time Copy: 23856.2 0.013412 0.013421 0.013455 Scale: 23512.8 0.013621 0.013633 0.013681 Add: 27891.4 0.017193 0.017206 0.017261 Triad: 27634.5 0.017355 0.017368 0.017422 -------------------------------------------------------------
判断带宽是否合理可以做个简单推算。以DDR4-3200内存、双通道为例,理论峰值带宽为3200MT/s乘以8字节再乘以2通道,约51.2GB/s,Stream实测能到七成即35GB/s左右算正常。如果你测出来只有理论值的三成,大概率是线程数没配对、虚拟机被限流或者宿主机超售严重。
排查异常时有三个常见坑。第一,忘了设置OMP_NUM_THREADS导致只用了少数核;第二,宿主机邻居负载波动,建议在业务低峰期多跑几次取稳定值,如果多次结果波动超过15%,说明这台实例的内存性能不稳定,跑关键业务要慎重;第三,某些云厂商的共享型实例本身就有CPU和内存带宽配额限制,这不是测试方法的问题,而是实例规格的设计如此,选型时应该避开突发性能型实例来跑内存敏感型业务。
把测试结果记录下来,配合lmbench、sysbench等其他基准工具的输出,你就能对一台云服务器建立完整的性能画像。购买新实例前花十分钟跑一遍Stream,往往能避免上线后才暴露的性能坑,这十分钟花得绝对值得。
Stream内存带宽测试云服务器性能测试STREAM TRIAD修改时间:2026-09-06 02:08:46