内存带宽测试报告与 STREAM 指南
摘要: 内存带宽往往是 AI 训练和 HPC 应用的实际瓶颈。本文基于经典的 STREAM 基准测试工具,详细介绍了 DDR5 服务器内存带宽的理论计算公式、编译优化参数(Intel OneAPI)以及实测案例分析。
1. 测试平台概览
本次测试旨在评估 Intel Sapphire Rapids 平台在不同内存插法下的带宽表现。
- CPU: 2 × Intel Xeon 8470 (Sapphire Rapids), 2.0 GHz, 52-Core
- 内存通道: 8 通道/CPU (Total 16 Channels)
- 内存配置:
- 半配: DDR5-4800 MHz (24 根, 64GB)
- 满配: DDR5-4400 MHz (32 根, 32GB)
- 测试目标: 验证 STREAM 实测带宽与理论峰值的差距 (Efficiency)。
2. 内存带宽理论计算
理论带宽由内存频率、通道数和数据位宽决定。
$$ \text{BW}_{\text{theory}} = \text{Freq (MT/s)} \times \text{CPU数量} \times \text{单CPU通道数} \times \frac{64\text{bit}}{8} $$
2.1 场景 A:半配 (24 DIMMs)
当内存未插满或运行在 1DPC (1 DIMM Per Channel) 模式下,频率通常较高。
- 配置: 24 根 DDR5-4800
- 计算: $4800 \times 2 \times 8 \times 8 = 614,400 \text{ MB/s}$
2.2 场景 B:满配 (32 DIMMs)
当插满 2DPC (2 DIMMs Per Channel) 时,为了信号完整性,内存频率通常会自动降级(如从 4800 降至 4400)。
- 配置: 32 根 DDR5-4400
- 计算: $4400 \times 2 \times 8 \times 8 = 563,200 \text{ MB/s}$
3. STREAM 基准测试原理
STREAM 是事实上的行业标准,通过四种向量运算模式评估内存子系统性能:
| 模式 | 操作 | 复杂度 | 说明 |
|---|---|---|---|
| Copy | a[i] = b[i] | 2 FLOPS | 纯数据移动 |
| Scale | a[i] = q * b[i] | 2 FLOPS | 简单的乘法 |
| Add | a[i] = b[i] + c[i] | 3 FLOPS | 两个向量相加 |
| Triad | a[i] = b[i] + q * c[i] | 3 FLOPS | 混合运算,最接近真实应用 |
性能规律
通常情况下:Triad ≈ Add > Copy > Scale 访存指令越密集,越能掩盖内存延迟,从而获得更高的带宽数值。
4. 编译与运行 (Intel 环境)
为了发挥硬件极限性能,必须使用 Intel C Compiler (icx) 并开启 Non-temporal Store (流式存储) 优化。
4.1 数组大小 (Array Size)
数组必须足够大,至少是 L3 Cache 总和的 4 倍,以确保测试的是内存而非缓存。
- 计算示例 (Xeon 8470): L3 Cache ≈ 105 MB × 2 = 210 MB。 推荐 Array Size > 800 MB。
DSTREAM_ARRAY_SIZE=100000000(约 768MB double 类型)
4.2 编译命令
# 加载 OneAPI 环境
source /opt/intel/oneapi/setvars.sh
# 编译 stream.c
icx stream.c -o stream_test \
-DNTIMES=100 \
-DOFFSET=0 \
-DSTREAM_TYPE=double \
-DSTREAM_ARRAY_SIZE=268435456 \
-Wall -O3 -mcmodel=medium \
-qopenmp \
-shared-intel \
-qopt-streaming-stores always-qopenmp: 开启多线程并行。-qopt-streaming-stores always: 关键参数,强制使用流式存储指令 (绕过缓存直接写内存),可显著提升写带宽。
4.3 运行配置
# 绑定线程以减少跨 NUMA 访问
export OMP_NUM_THREADS=104 # 设置为物理核心总数
export KMP_AFFINITY=compact,granularity=fine
./stream_test5. 实测结果分析
以满配 32 根 DDR5-32G (4400 MHz) 为例:
- 理论带宽: 563,200 MB/s
- 实测数据:
| 测试项 | 带宽 (MB/s) |
|---|---|
| Copy | 400,376 |
| Scale | 385,210 |
| Add | 403,436 |
| Triad | 403,436 |
5.1 效率计算 (Efficiency)
$$ \text{Efficiency} = \frac{\text{Measured Triad}}{\text{Theoretical BW}} = \frac{403,436}{563,200} \approx 71.6% $$
5.2 结论
- 正常范围: 双路服务器的内存带宽效率通常在 68% ~ 75% 之间。本次测试结果 (~71%) 属于正常水平。
- 指令集影响: 在 STREAM 这类纯访存密集型测试中,AVX-512 相比 AVX2 对带宽的提升并不明显,瓶颈在于内存通道本身。
- 容量权衡: 满配内存虽然容量大,但由于频率降低 (4800 -> 4400),理论带宽上限会下降,实际业务需在容量与速度间权衡。
6. 注意事项
- 避免 NUMA 陷阱: 务必确保
OMP_NUM_THREADS与 CPU 核心数匹配,且KMP_AFFINITY设置正确。如果线程在不同 NUMA 节点间乱跳,带宽可能减半。 - GLIBC 依赖: 新版 Intel 编译器编译的程序可能依赖较新的
glibc,在老旧系统 (如 CentOS 7) 上运行需注意库路径。 - Array Size: 如果结果异常高 (接近 L1/L2 速度),检查
STREAM_ARRAY_SIZE是否设置过小。
