DDR5+CXL 3.0服务器如何验证内存池利用率接近90%且性能可接受?
要验证 DDR5+CXL 3.0 服务器是否真的把内存池利用率从约 40%提升到接近 90%,不能只看 free -h 中的 Used 数值,也不能只运行一次内存压力工具。有效验收应同时证明三件事:实际工作集已经驻留在目标容量范围内,CXL 内存确实被业务访问,且在目标并发下吞吐、尾延迟、CPU 消耗和内存稳定性仍符合业务要求。
实际测试时,建议把 90%定义为“可分配内存池中约 85%~92%的容量被真实触碰并持续使用”,而不是把物理内存完全填满。以 1 TB 可用内存池为例,约 900 GB 活跃驻留并不意味着可以继续无条件加压,仍要为内核、页表、连接缓冲区、突发流量和内存碎片保留空间。所谓 DDR5+CXL 3.0 实测,重点不是得出一个脱离环境的固定性能数字,而是找到性能开始明显恶化前的容量拐点。
先定义“90%利用率”和“性能可接受”
内存池利用率应采用下面的口径:
内存池利用率 = 实际驻留且被工作集使用的内存 ÷ 可分配内存池容量 × 100%
其中,“实际驻留”要排除仅通过 malloc 或 mmap 申请、但从未写入和读取的虚拟地址;“可分配容量”也不能直接照搬物理内存条标称容量,而应扣除固件预留、系统保留、不可用区域以及不允许业务使用的容量。
验收时最好同时记录三种容量:

- 主机总内存池容量:DDR5 本地内存与可供操作系统或应用使用的 CXL 内存之和。
- 业务工作集容量:目标进程实际使用的匿名页、文件页或应用缓存。
- CXL 驻留容量:工作集里实际位于 CXL NUMA 节点或 CXL 内存区域的部分。
例如,主机向业务提供 1 TB 内存池,测试时业务实际驻留 900 GB,则池利用率约为 90%。如果其中只有 30 GB 位于 CXL 节点,剩余部分仍在 DDR5,那么这只能说明业务占用了 90%的总容量,不能充分证明 CXL 池化路径正在承担目标负载。
“性能可接受”则必须绑定到业务基线。没有明确业务SLA时,可以先使用一组临时验收边界:
- 目标容量下吞吐量不低于 DDR5基线的 90%;
- p95 延迟增幅不超过 20%,p99 延迟增幅不超过 25%;
- 热身结束后不出现持续交换,不出现不断增长的 major page fault;
- 单请求 CPU 消耗增幅不超过 15%;
- 目标测试时长内没有 CXL 设备错误、链路重置或内存校验错误。
这些数值只是便于验收的参考边界。在线交易、缓存、分析任务和批处理任务的容忍度不同,最终应以业务延迟和吞吐要求覆盖这些参考值。
测试环境必须先固定
CXL 内存的访问延迟和带宽会受到处理器插槽、NUMA节点、CXL设备挂载位置、交换路径、固件内存策略和操作系统内核的共同影响。相同容量的两台服务器,如果内存交织策略或CXL区域配置不同,测试结果也可能不同。
建议在正式压测前记录以下信息:
| 项目 | 需要固定或记录的内容 |
|---|---|
| 服务器拓扑 | CPU插槽数量、DDR5通道和容量、CXL设备或CXL内存池挂载位置 |
| CXL状态 | CXL设备是否枚举、内存区域是否在线、是否以NUMA内存或其他方式暴露 |
| 固件设置 | NUMA、内存交织、内存镜像、功耗策略、CXL相关开关 |
| 操作系统 | 发行版、内核版本、CXL和NUMA支持情况 |
| 内核内存策略 | 自动NUMA平衡、透明大页、交换策略、内存分层或页面迁移策略 |
| 业务程序 | 版本、数据集大小、缓存命中率、线程数、连接数、请求模型 |
| 测试周期 | 预热时长、正式采样时长、重复次数、冷启动或热启动状态 |
可以先使用只读命令确认主机识别到的拓扑:
uname -a
lscpu
numactl -H
numastat -m
free -h
cat /proc/swaps
sysctl vm.zone_reclaim_mode vm.swappiness kernel.numa_balancing
if [ -f /sys/kernel/mm/transparent_hugepage/enabled ]; then
cat /sys/kernel/mm/transparent_hugepage/enabled
fi
如果系统安装了 CXL 工具,也可以查看设备和区域的枚举情况:
if command -v cxl >/dev/null 2>&1; then
cxl list
else
echo "cxl command is not installed"
fi
dmesg --level=err,warn | grep -i cxl || true
这些输出可以证明设备是否被系统发现、内存区域是否有异常,但不能仅凭 cxl list 或 lspci 的一行信息断定所有路径都符合 CXL 3.0能力。CXL版本、交换拓扑和内存池能力仍应以服务器固件、设备配置和平台文档中的实际配置为准。测试报告中至少应保存命令输出和测试日期,避免后续复测时误把不同拓扑当成同一环境。
还要明确CXL内存的暴露方式。如果它被操作系统作为普通NUMA内存提供,可以通过节点级统计观察驻留分布;如果它以DAX或应用直接映射方式提供,则不能只依赖 free -h 和普通NUMA统计,应同时记录应用映射、访问量和设备侧监控数据。
建立40%、70%、85%、90%和95%的测试阶梯
不要从40%直接跳到90%,否则很难判断性能下降是渐进发生,还是在某个容量点突然恶化。建议至少设置以下阶梯:
| 测试档位 | 目标池利用率 | 主要用途 |
|---|---|---|
| 基线 | 约40% | 记录DDR5本地内存下的吞吐、延迟和CPU消耗 |
| 扩展一 | 约70% | 观察少量CXL驻留时的变化 |
| 扩展二 | 约85% | 判断接近目标容量时是否出现尾延迟上升 |
| 目标档 | 约90% | 验证目标容量下能否满足业务SLA |
| 压力档 | 约95% | 寻找性能拐点,不作为日常运行容量 |
每个档位都要让内存页面真正被访问。仅仅申请一块900 GB的虚拟地址空间,不能证明900 GB已经被使用。测试程序或业务回放应写入并读取目标工作集,并保持一段时间,确保页面已经建立、分配并持续参与请求处理。
对于业务型测试,建议分成两组对照:
- 固定工作集对照:保持数据量、请求分布和并发数不变,分别让工作集尽量落在DDR5和CXL内存上,用来测量CXL访问本身带来的延迟和带宽代价。
- 容量扩展验收:从40%逐步增加到90%,保持请求模型、缓存命中率和业务逻辑不变,用来验证内存池扩容后业务是否仍能运行。
如果40%时数据集较小、缓存命中率为99%,90%时数据集扩大后命中率下降到90%,那么吞吐下降不能全部归因于CXL。此时应先修正测试模型,或者在报告中明确区分“容量变化影响”和“CXL访问影响”。
采集哪些指标,分别说明什么
1. 容量和驻留分布
主机级容量可以通过节点内存统计和CXL区域状态观察,但业务验收还要看进程或容器级工作集。
对于单个进程,可以记录:
PID=12345
grep -E 'VmRSS|VmSwap|RssAnon|RssFile' /proc/${PID}/status
cat /proc/${PID}/smaps_rollup | grep -E '^(Rss|Pss|Swap):'
numastat -p "${PID}"
如果业务运行在 cgroup v2 中,还应记录容器或服务组的内存消耗:
CGROUP_PATH=/sys/fs/cgroup/my-service
if [ -f "${CGROUP_PATH}/memory.current" ]; then
cat "${CGROUP_PATH}/memory.current"
cat "${CGROUP_PATH}/memory.stat"
cat "${CGROUP_PATH}/memory.swap.current"
fi
需要注意:
VmRSS适合观察进程实际驻留,但共享页在多个进程中的统计方式可能不同;memory.current包含该cgroup的匿名页、文件页等,不等于纯业务数据;free -h中的缓存并不一定是业务热数据;numastat -p可以观察进程在不同NUMA节点的驻留,但节点与CXL设备的对应关系要先通过拓扑确认;- 如果页面迁移策略开启,测试过程中页面可能从CXL回迁到DDR5,导致“总容量达到90%但CXL驻留量很低”的假象。
验收报告至少应同时写出“总池利用率”和“CXL驻留量或CXL访问量”,不能只写一个百分比。
2. 延迟:优先看p95和p99
平均延迟容易掩盖CXL远端访问、内存争用和页面迁移产生的长尾。建议至少记录 p50、p95、p99,必要时增加最大值和每分钟的延迟分布。
- p50:典型请求的中位延迟;
- p95:大多数请求的体验;
- p99:尾部请求和突发内存访问的影响;
- 最大值:适合发现异常,但不应单独作为验收依据。
如果40%基线的p99为1.8 ms,90%目标档为2.2 ms,则增幅约为:
(2.2 - 1.8) ÷ 1.8 × 100% ≈ 22.2%
若业务允许p99增幅不超过25%,这个结果可以进入“可接受”范围;如果业务SLA要求p99不超过2 ms,即使吞吐仍然稳定,也应判定为不合格。
3. 吞吐量和并发
吞吐量应使用业务可理解的单位,例如请求数/秒、事务数/秒、批处理记录数/分钟或查询数/秒,而不是只使用内存带宽。
测试时保持并发模型一致,并分别记录:
- 固定并发下的最大稳定吞吐;
- 固定吞吐下的p95和p99延迟;
- 排队长度和超时率;
- 业务错误率;
- 线程数和连接数;
- 缓存命中率或数据访问分布。
如果在90%利用率下吞吐只下降5%,但p99上升60%,仍不能简单判定为性能可接受。反过来,如果吞吐下降10%,但延迟没有超出业务SLA,也要确认是否是CPU已经达到上限,而不是CXL访问本身造成的。
4. CPU消耗和每请求成本
CXL访问可能不会明显增加系统总内存使用,却会增加CPU等待、内存访问停顿或页面管理开销。因此要同时看CPU利用率和每请求CPU成本。
可以使用以下命令观察进程的硬件计数器;具体事件是否可用,以本机 perf list 输出为准:
PID=12345
perf list | grep -Ei 'cache|memory|numa|cxl' | head -n 50
perf stat -p "${PID}" \
-e cycles,instructions,cache-misses,minor-faults,major-faults \
-- sleep 60
重点不是某一个计数器的绝对值,而是和40%基线比较:
- 吞吐不变、CPU利用率略升,通常说明CXL访问仍在可控范围;
- 吞吐下降、CPU利用率明显上升,可能是远端访问、锁竞争或页面迁移;
- CPU利用率不高但p99暴涨,可能存在内存访问停顿、设备排队或少量严重长尾;
perf无法访问某些硬件事件时,不要自行替换成不兼容的事件名称,应使用应用指标、NUMA统计和平台监控补充。
5. 页面错误、交换和I/O等待
正常的业务内存池验收不应依赖交换空间来“挤出”90%利用率。采集过程中要记录:
vmstat 1 60
iostat -xz 1 60
cat /proc/vmstat | grep -E 'pgfault|pgmajfault|pswpin|pswpout'
预热阶段可能出现少量页面建立和缺页,正式采样阶段则应关注:
pgmajfault是否持续增长;pswpin和pswpout是否出现;- I/O等待是否随着容量增加而上升;
- 业务延迟尖峰是否和页面回收或交换时间一致。
如果90%档位已经开始交换,或者major fault在正式采样期间持续增长,即使内存池显示达到了90%,也不应作为合格的生产容量。此时通常需要降低目标利用率、调整工作集或重新检查内存放置策略。
一套可复现的测试方法
先采集40%基线
基线不是“随便空闲一台机器”,而是与目标档位使用同一套应用、同一数据访问模式和同一并发模型。建议:
- 预热10~15分钟,让缓存、连接池和内存分配稳定;
- 正式采样至少30分钟;
- 重复3次,记录中位结果和最差结果;
- 固定CPU频率策略、线程数、进程数量和数据集;
- 记录冷启动与热启动状态,不能把两者混在一起比较。
基线报告中至少保存:池利用率、DDR5驻留量、CXL驻留量、吞吐、p50/p95/p99、CPU利用率、每请求CPU、major fault、swap、错误率和内存带宽。
逐步增加实际工作集
从40%开始,每次增加5%~10%的工作集。每次扩容后,先确认页面确实被触碰,再开始正式采样。对于使用内存分配器的应用,应记录分配器统计;对于缓存系统,应记录实际缓存容量和命中率;对于数据库或分析任务,应记录有效数据集和临时内存。
如果服务器把CXL暴露为多个NUMA节点,可以使用 numactl -H 查询节点编号,再结合应用的NUMA策略进行验证。不要直接照抄其他服务器的 --membind 节点编号,因为不同固件和插槽布局可能完全不同。
测试过程中要特别记录以下内核策略是否保持一致:
- 自动NUMA平衡是否开启;
- 页面是否允许在DDR5与CXL节点之间迁移;
- 透明大页策略是否改变;
- CXL内存是否被设置为优先节点、后备节点或独立区域;
- 应用是否自行绑定了线程和内存。
如果生产环境允许页面迁移,测试也应允许;如果生产环境要求工作集长期驻留在CXL,测试则应限制迁移并单独验证。否则测试结果可能只反映“系统自动把热点数据搬回DDR5”的能力,而不是内存池在90%利用率下的真实表现。
90%目标档位进行稳定运行
达到目标容量后,不要立即读取一次监控就结束。建议至少连续运行30~60分钟,观察是否出现延迟随时间增长、CXL驻留量下降、页面回迁、内存回收或错误累积。
对延迟敏感的服务,还应分别测试:
- 低并发:观察单请求访问代价;
- 目标并发:判断实际生产体验;
- 峰值并发:观察尾延迟和排队;
- 固定吞吐:判断内存访问是否会造成超时;
- 固定容量:判断在不同CXL驻留比例下的变化。
压力档可以做到95%,但应在隔离环境或维护窗口内进行,并为测试进程设置明确的资源上限。95%的结果主要用于找性能拐点,不建议直接作为生产运行目标。
示例结果如何解释
下面是一组用于说明判断方法的模拟数据。假设可供业务使用的DDR5+CXL内存池为1 TB,40%档位作为基线,业务请求模型和并发保持一致。数据不是某台具体服务器的实测结果,实际数值应以现场采样为准。

| 池利用率 | CXL驻留量 | 吞吐量 | p99延迟 | CPU利用率 | 正式采样期major fault | 判断 |
|---|---|---|---|---|---|---|
| 40% | 0 GB | 100,000 req/s | 1.8 ms | 62% | 0 | DDR5基线 |
| 70% | 180 GB | 99,000 req/s | 1.9 ms | 65% | 0 | 变化较小 |
| 85% | 320 GB | 97,000 req/s | 2.0 ms | 67% | 0 | 接近目标 |
| 90% | 420 GB | 94,000 req/s | 2.2 ms | 70% | 0 | 在示例边界内 |
| 95% | 470 GB | 86,000 req/s | 3.9 ms | 85% | 120次/分钟 | 出现性能拐点 |
以40%为基线,90%档位的吞吐量约为基线的94%,p99延迟增幅约22.2%,CPU利用率增幅约12.9%,且正式采样期间没有major fault。按照前述参考边界,这个90%档位可以判定为“性能可接受”。
95%档位虽然只比90%多使用约50 GB,但吞吐明显下降,p99延迟接近翻倍,同时出现major fault。这说明性能恶化不是按容量线性变化,而是在90%~95%之间进入了拐点。生产容量不应根据“还能装下多少数据”决定,而应选在性能拐点之前。
常见的“90%假象”
只看宿主机Used,不看业务驻留
Linux的Used可能包含页缓存、共享页和其他服务占用。宿主机看起来达到90%,不代表目标业务使用了90%的池容量。应同时记录业务进程、cgroup和NUMA节点的分布。
只申请虚拟内存,没有实际触碰页面
malloc、mmap或容器内存上限只能说明地址空间或配额发生变化。测试程序必须写入和读取页面,业务回放则要确保数据确实被访问。
CXL已枚举,但业务没有访问CXL
设备被系统识别并不等于业务使用了CXL。可能存在以下情况:
- CXL区域处于在线状态,但分配策略仍优先使用DDR5;
- 页面在分配后被自动迁移回DDR5;
- CXL以应用直接映射方式提供,普通NUMA统计无法完整反映;
- 测试工作集没有超过DDR5可用容量;
- 业务只占用CXL容量,但热点数据仍全部位于本地DDR5。
因此,验收报告应同时给出CXL驻留量、节点访问统计或设备侧计数,而不是只写“CXL已启用”。
只看平均延迟,不看尾延迟
CXL远端访问、队列拥塞和页面迁移往往只影响一小部分请求。平均值可能仍然很好,但p99已经超出业务SLA。对交易、缓存和在线查询服务,p95、p99通常比平均值更有决策价值。
用I/O监控代替CXL监控
CXL内存访问不是普通磁盘I/O。iostat主要用于发现交换、回收和存储等待,不能单独证明CXL链路带宽和访问质量。CXL相关判断需要结合NUMA驻留、硬件计数器、平台遥测或应用级延迟。
测试时允许系统自动回迁,生产时却不允许
如果测试期间内核把热点页自动迁移到DDR5,结果可能比生产环境更好。反之,如果生产环境允许迁移而测试强制绑定CXL,结果又可能过于悲观。必须记录内存分层和迁移策略,并保持测试与生产一致。
什么时候可以判定验收通过
可以将验收结果分为三类,而不是简单写成“通过”或“不通过”。

容量和性能同时通过:
- 实际工作集稳定在目标池利用率,例如88%~92%;
- CXL驻留量或访问量达到预期;
- 吞吐、p95、p99和错误率符合业务SLA;
- 正式采样期间没有持续交换和异常major fault;
- CPU增加仍在可接受范围;
- 连续运行期间没有设备错误或链路异常。
容量达到,但性能不通过:
- 总池利用率达到90%;
- 但p99明显超标、吞吐下降、CPU消耗过高或出现页面回收;
- 此时应把性能拐点之前的85%或更低容量作为候选运行点,而不是为了达到90%继续扩容。
看似通过,但证据不足:
- 总容量达到90%,但CXL驻留量不明;
- 只测了几分钟;
- 只记录平均延迟;
- 业务数据集和40%基线不同;
- 没有记录缓存命中率、线程数或页面迁移策略。
这类结果不能证明内存池利用率和CXL性能已经达标,应补充测试后再作决定。
复测条件和最终容量判断
出现以下变化时,应重新执行至少一轮40%、85%、90%和压力档测试:
- BIOS、固件、内核或CXL工具版本发生变化;
- DDR5容量、内存通道、插槽或交织策略发生变化;
- CXL设备、交换路径或内存池大小发生变化;
- NUMA绑定、页面迁移、透明大页或交换策略发生变化;
- 业务版本、数据集规模、缓存命中率或并发模型发生变化;
- 服务器从冷启动变为长期热运行,或反过来;
- 90%档位出现过异常延迟、交换或设备错误。
最终容量可以按下面的方法确定:
建议生产容量 = 性能拐点之前的稳定驻留容量,并与业务预留比例取较小值。
例如,90%档位吞吐和p99仍稳定,95%档位明显恶化,则90%可以作为候选目标;如果90%已经出现长尾,而85%稳定,则应将85%附近作为生产容量,并为突发请求保留余量。对于无法建立明确业务SLA的场景,至少保留10%~15%的可用空间,并通过连续运行和峰值并发测试确认这部分余量足以吸收短时波动。
真正可靠的验收结果,不是“内存条被填到了90%”,而是能够在固定拓扑、固定工作集和固定并发下,证明DDR5与CXL内存都按预期承担了访问,同时业务吞吐和尾延迟没有跨过可接受边界。只有容量、放置、性能和稳定性四组指标同时成立,90%的内存池利用率才具有生产参考价值。