title: 内存测试
created: 2026-06-20
updated: 2026-06-20
type: concept
tags: [memory, benchmark, stress-test]
sources:
- raw/scripts/0内存.sh
- raw/scripts/mem.sh
- raw/scripts/mlc.sh


内存测试

内存测试涵盖信息查看、带宽/延迟基准测试稳定性压力测试三大类。本文重点解析 STREAM 基准测试的各项指标。


1. 内存基本信息查看

dmidecode

通过 DMI/SMBIOS 读取物理内存硬件信息:

sudo dmidecode -t memory          # 查看所有内存信息
sudo dmidecode -t 16              # 查看物理内存阵列
sudo dmidecode -t 17 | awk -F': ' '
BEGIN {
    printf "%-5s %-15s %-20s %-25s %-10s\n", "Line", "Locator", "Serial", "Size-Type-Speed", "Part Number"
}
/Size:/ { size = $2 }
/Bank Locator:/ { locator = $2 }
/Type:/ { type = $2 }
/Configured Memory Speed:/ { speed = $2 }
/Serial Number:/ { serial = $2 }
/Part Number:/ { part = $2 }
/Firmware Version:/ {
    combined = size "-" type "-" speed
    printf "%-5d %-15s %-20s %-25s %-10s\n", line++, locator, serial, combined, part
}'

关键字段解读:
- Size — 单条容量(如 32 GB)
- Type — 内存类型(DDR4 / DDR5 / DDR3)
- Configured Memory Speed — 运行频率(如 3200 MT/s)
- Part Number — 部件号,用于确认厂商和型号

free -h

快速查看系统内存使用概览:

free -h

输出包括总容量(total)、已用(used)、可用(available)、缓存/缓冲区(buff/cache)等。

lsmem

查看内存布局和每个内存块的状态:

lsmem

显示每个内存段的起始地址、结束地址、大小、状态(online/offline)和 zone(如 Movable)。

内存缓存清理

在测试前清理页缓存、dentry 和 inode 缓存,避免缓存内容影响内存或磁盘测试结果:

echo 3 > /proc/sys/vm/drop_caches

说明:写入 1 只清理页缓存,写入 2 清理 dentries/inodes,写入 3 清理全部(最彻底)。在 STREAM 等内存带宽测试和 FIO/iozone 磁盘测试前均应执行。

参见:cpu-testing(测试前后清理缓存)、disk-storage-testing(磁盘测试前必须清理)


2. STREAM 内存带宽基准测试

STREAM 是业界最主流的内存带宽测试工具,通过四种向量运算操作测量可持续内存带宽

获取与编译

curl -OL http://www.cs.virginia.edu/stream/FTP/Code/stream.c

gcc -fopenmp \
    -mtune=native -march=native \
    -O3 \
    -DSTREAM_ARRAY_SIZE=100000000 \
    -DNTIMES=100 \
    -DOFFSET=4096 \
    -mcmodel=medium \
    stream.c -o stream

编译参数详解:

参数 说明
-fopenmp 启用 OpenMP 多线程支持,默认线程数等于 CPU 逻辑核心数
-mtune=native -march=native 针对当前 CPU 指令集优化(ARM 平台需取消)
-O3 最高编译优化级别
-DSTREAM_ARRAY_SIZE=N 数组大小(元素个数),建议 ≥ L3 缓存大小 × 4 / 8,确保内存压力而非缓存命中
-DNTIMES=N 每项运算重复次数,取最优值(建议 100+),越大结果越稳定
-DOFFSET=N 数组偏移量(可选),用于避免缓存行争用
-mcmodel=medium 当数组大小超过 2 GB 时需要,解除大内存限制

数组大小计算推荐:

# 自动根据 L3 缓存计算数组大小
gcc -fopenmp -O3 -march=native -mtune=native \
    -DNTIMES=100 \
    -DSTREAM_ARRAY_SIZE=$(lscpu | awk '/L3/{sz=$3; u=$4; if(u=="MiB")sz=sz*1024*1024; else if(u=="KiB")sz=sz*1024; print int(sz/8/3)}') \
    -DOFFSET=0 -DSTATIC= stream.c -o stream

运行与绑核

# 清理缓存
echo 3 > /proc/sys/vm/drop_caches

# 多线程(默认使用所有 CPU 核心)
export OMP_NUM_THREADS=$(lscpu | awk '/CPU\(s\):/{printf("%d\n",$2)}' | grep -v 0)
./stream

# 单线程(对比测试)
export OMP_NUM_THREADS=1
./stream

# 绑核运行(避免跨 NUMA 节点调度)
export GOMP_CPU_AFFINITY=0-127

四项指标详解

STREAM 输出四个核心指标,单位均为 MB/s

指标 运算操作 含义 典型特征
Copy c[i] = a[i] 仅读+写,纯内存带宽 通常最高值,接近理论带宽的 80-90%
Scale b[i] = scalar × c[i] 读+乘法+写 略低于 Copy(多了 ALU 操作开销)
Add c[i] = a[i] + b[i] 读两个数组+加法+写 比 Copy 稍低(需要两倍读取带宽)
Triad a[i] = b[i] + scalar × c[i] 乘+加混合(最接近实际负载 业界最广泛引用的综合带宽指标

结果解读:

-------------------------------------------------------------
Function    Best Rate MB/s  Avg time     Min time     Max time
Copy:           51234.5     0.015625     0.014203     0.017302
Scale:          50876.2     0.015756     0.014312     0.017890
Add:            53421.8     0.023451     0.020310     0.025109
Triad:          53100.3     0.023402     0.020430     0.025401
-------------------------------------------------------------

批量运行与结果提取

# 三次运行取稳定值
echo "" > stream.out
for i in {1..3}
do
    echo 3 > /proc/sys/vm/drop_caches
    export OMP_NUM_THREADS=$(lscpu | awk '/CPU\(s\):/{printf("%d\n",$2)}' | grep -v 0)
    ./stream >> stream.out
done

# 提取 CSV 格式结果
cat stream.out | grep -E "Copy:|Scale:|Add:|Triad:" | awk '/:/{gsub(/:/,"",$1); print $1","$2","$3","$4","$5}' > stream_results.csv

3. Intel MLC 内存测试

Intel Memory Latency Checker(MLC)可同时测量内存延迟矩阵带宽矩阵

# 延迟测试 — 输出跨核心/跨 NUMA 的延迟矩阵
./mlc --latency_matrix

# 带宽测试 — 输出各 NUMA 节点间的带宽
./mlc --bandwidth_matrix

4. 内存压力 / 稳定性测试

stress

通用的系统压力测试工具:

# 内存压力:50 个 vm 进程,每个分配 5G,挂起 100 秒,测试 12 小时
stress -i 4 --vm 50 --vm-bytes 5G --vm-hang 100 --timeout 43200s

# 按剩余内存的 1/8 分配 8G 每个,测试 12 小时
date && stress -m $(free -g | awk '/Mem/{printf("%.0f\n",$4/8)}') --vm-bytes 8G --vm-hang 5 -t 43200s

memtester

用户态内存稳定性测试,检测内存故障:

# 下载编译
curl -Ol http://pyropus.ca/software/memtester/old-versions/memtester-4.5.0.tar.gz
tar -zxf memtester-4.5.0.tar.gz
cd memtester-4.5.0
make

# 测试 32G 内存,执行 1 遍
date && ./memtester 32G 1 && date

# 按剩余内存的 80% 测试
date && ./memtester $(free -m | awk '/Mem/{printf("%.0f\n",$4*0.8)}') 1 && date

参数: memtester <内存大小> <迭代次数>

结果解读:测试通过无输出即为 PASS。如果检测到故障会输出 "FAIL" 及具体出错地址。

mbw

内存带宽快速评估:

mbw -q -n 3 4096

ramspeed

对整数/浮点内存读写带宽的细分测试:

# 整型写
./ramsmp -b 1
# 整型读
./ramsmp -b 2
# 浮点写
./ramsmp -b 4
# 浮点读
./ramsmp -b 5

5. lmbench 内存微基准

lmbench 的 lat_mem_rd 测试内存延迟(ns)随工作集大小的变化曲线:

# 运行全部 lmbench 测试
make results
make see

内存延迟结果通常以 ns 呈现,数值越小越好。当工作集超过 L3 缓存大小时,延迟显著上升(L3 hit 约 10-30 ns → 内存访问约 60-120 ns)。


关键指标对比

工具 测试类型 主要关注指标 适用场景
STREAM 带宽 Copy/Scale/Add/Triad (MB/s) 标准内存带宽验收
MLC 延迟+带宽 latency_matrix, bandwidth_matrix NUMA 拓扑分析
memtester 稳定性测试 PASS/FAIL + 地址 内存故障排查
stress 压力负载 是否 OOM/crash 系统稳定性验证
mbw 快速带宽 MEMCPY/DUMB/MCBLOCK (MB/s) 快速粗测
ramspeed 读写细分 INT/FLOAT 读写带宽 分类性能分析
lmbench 微基准 延迟 (ns) 缓存/内存层级分析

出链