云主机的性能评估中,CPU核心数量和主频往往最先被关注,但内存带宽对实际吞吐的影响同样关键。如果应用频繁读写大块数据,比如科学计算中的矩阵运算、内存数据库的键值存取、实时流处理的状态管理,内存带宽不足会让CPU等待数据,核心再多也发挥不出来。Google Cloud提供了多种实例系列,不同规格背后的内存控制器、通道数和NUMA拓扑差异很大,仅看规格表很难判断真实带宽。本文使用STREAM基准测试对Google Cloud主流实例进行实测,对比单线程与满核并发下的带宽表现,并分析影响测试结果的关键因素。

STREAM基准测试方法与测试条件
STREAM是评估可持续内存带宽的经典工具,由John McCalpin在1991年提出,至今仍是高性能计算领域衡量内存子系统性能的事实标准。它通过四个向量操作来测量带宽:Copy操作执行a(i)=b(i),只涉及一次读和一次写;Scale操作执行a(i)=q*b(i),带有标量乘法;Add操作执行a(i)=b(i)+c(i),包含两次读和一次写;Triad操作执行a(i)=b(i)+q*c(i),同样两次读一次写但混合了乘加运算。通常Triad的带宽数据最具代表性,因为它最接近实际浮点计算中的访存模式。
为了保证测试结果不受CPU缓存干扰,数组大小必须远大于最后一级缓存。以常见的32MB LLC为例,每个数组至少需要数百MB,例如设置STREAM_ARRAY_SIZE为100000000时,三个双精度数组共占用约2.4GB内存,足够避免缓存复用。测试还需要控制线程数,使其与物理核匹配,而不是超线程逻辑核,否则会出现线程争用同一个物理核的访存通路,导致带宽数据偏低。下面的命令展示了在Google Cloud Linux实例上编译和运行STREAM的典型过程。
# 下载STREAM源码 wget https://www.cs.virginia.edu/stream/FTP/Code/stream.c # 使用OpenMP编译,数组大小设为1亿个元素,重复10次 gcc -O3 -fopenmp -DNTIMES=10 -DSTREAM_ARRAY_SIZE=100000000 stream.c -o stream # 设置线程数为8并运行 export OMP_NUM_THREADS=8 ./stream
运行完成后,程序会输出Copy、Scale、Add、Triad四个操作的平均带宽、最大带宽和最小带宽,单位是MB/s。建议连续运行三次取平均值,并观察波动范围。如果单次运行中最小带宽与平均带宽差距超过3%,说明测试环境可能存在噪声,需要检查是否被其他租户干扰。
Google Cloud不同实例规格的实测数据对比
为了直观比较,我们在Google Cloud同一区域选择了几款有代表性的实例规格,分别运行STREAM基准测试。测试采用Ubuntu 22.04操作系统,内核版本5.15,关闭透明大页以减少页面映射开销。每款实例均运行满核并发测试,线程数设置为vCPU数量,同时记录单线程带宽作为基准。表中数据为三次运行的平均值。
| 实例规格 | vCPU数 | 内存(GB) | 单线程Triad带宽(GB/s) | 满核Triad带宽(GB/s) |
|---|---|---|---|---|
| N2-standard-8 | 8 | 32 | 12.2 | 38.4 |
| N2D-standard-8 | 8 | 32 | 12.9 | 41.7 |
| C2-standard-8 | 8 | 32 | 15.3 | 52.1 |
| C2D-standard-8 | 8 | 32 | 16.1 | 58.9 |
| M1-megamem-96 | 96 | 1433 | 9.6 | 30.2 |
从数据可以看出,C2D-standard-8的满核Triad带宽最高,达到58.9 GB/s,比N2-standard-8高出约53%。C2D采用AMD EPYC第四代处理器,支持DDR5内存,内存通道效率更高。N2D虽然是第二代AMD EPYC平台,带宽表现也优于同期的N2系列。M1-megamem-96虽然拥有96个vCPU和1.4TB内存,但满核带宽只有30.2 GB/s,说明内存带宽并不随核心数线性放大,该系列更侧重容量而非速度。
单线程带宽方面,各实例均在9到16 GB/s之间,C2D同样领先,但差距远小于满核并发。这说明单线程性能受限于单个核心的访存能力,而满核并发时内存通道竞争成为瓶颈。如果应用只使用单线程或者并发度很低,那么实例之间的带宽差异不会很明显;反之,高并发内存密集型负载更依赖机型的通道配置。
影响云环境内存带宽的关键因素
云环境中的内存带宽并非固定值,它受多个层面因素共同作用。首先是物理机上的NUMA拓扑。多路服务器会划分多个NUMA节点,每个节点拥有本地内存。若vCPU被调度到NUMA节点0,但内存页分配在节点1,就会产生跨节点访问,时延和带宽都会明显下降。使用numactl命令可以查看当前实例的NUMA结构,并将进程绑定到指定节点。
# 查看NUMA节点和CPU映射 numactl --hardware # 绑定进程到NUMA节点0的CPU和内存 numactl --cpunodebind=0 --membind=0 ./stream
其次是vCPU与物理核的映射关系。云厂商通常将超线程逻辑核也作为vCPU售卖,两个vCPU可能共享同一个物理核的执行单元和缓存。满核并发时,如果应用被迫与其他vCPU争抢同一物理核,实际可用的内存并行度会减半。测试STREAM时,建议通过lscpu查看物理核和逻辑核的对应关系,将线程数设置为物理核数量,避免超线程干扰。
第三是内存通道数和频率。理论带宽等于通道数乘以每通道数据率,例如8通道DDR5-4800的理论带宽约为307.2 GB/s,但虚拟机分配到的vCPU通常只能访问部分内存控制器。C2D系列由于采用更新的平台和更高的内存频率,在相同vCPU数量下能提供更高的带宽。最后,云平台的多租户共享也会带来噪声。同一物理主机上的其他实例可能同时进行高内存访问,导致你的STREAM测试结果出现周期性波动。如果发现带宽波动超过5%,建议更换时段或选择独享型实例重新验证。
如何根据负载类型选择Google Cloud实例
从实测结果来看,内存带宽敏感型负载应优先考虑C2D系列。例如Redis、Memcached等内存数据库需要频繁读写内存中的键值对,高带宽可以提升每秒操作数。科学计算中的矩阵乘法和流体动力学模拟通常需要连续遍历大数组,Triad带宽直接决定迭代速度。C2D-standard-8的58.9 GB/s满核带宽能够显著缩短这类任务的计算时间。
对于需要超大内存但访问模式相对稀疏的场景,比如大型图数据库、内存缓存分层、或者需要将整个数据集驻留内存的批处理作业,M1或M2系列的内存容量优势更关键。虽然其带宽较低,但如果应用本身不追求极高的访存速率,选择大内存实例可以避免磁盘交换带来的巨大性能损失。此时应优先考虑容量而非带宽。
无论选择哪种实例,都建议在部署前自行运行STREAM测试。不同区域、不同可用区的实例可能因为硬件代际差异导致带宽表现不同。一个简单的验证流程是:创建实例后,按照上文方法编译运行STREAM,记录满核Triad带宽;再运行自己的应用进行小规模压力测试,对比性能是否匹配预期。如果实测带宽与表格数据差距超过20%,可以尝试更换实例类型或联系云服务商确认底层硬件状态。
总的来说,Google Cloud Stream内存带宽评测揭示了实例规格与实际性能之间并非简单对应。理解STREAM测试原理,结合NUMA绑定和线程设置,能够帮助选出真正适合内存密集型负载的机型,避免为用不上的带宽或者不够用的带宽付出代价。
Google Cloud内存带宽STREAM基准测试修改时间:2026-09-21 21:14:29