如何测试随机访问工作负载下的内存带宽极限?
测试完全随机读取工作负载下的内存带宽极限
针对指针追踪因指令强依赖导致带宽受限于CPU流水线延迟的问题,可通过以下几种方法突破瓶颈,测试内存通道的真实随机访问带宽:
1. 多线程独立指针追踪
单线程指针追踪因指令串行依赖只能发起少量并行内存请求,多线程可通过并行发起独立请求充分利用内存的多请求处理能力:
- 为每个线程分配独立、无重叠的内存块,预先在每个块内构建随机指针链,避免线程间缓存干扰。
- 线程数量建议匹配CPU逻辑核心数,或按内存通道数调整(比如每通道分配2-4个线程),最大化并行请求量。
- 每个线程持续执行指针追踪,统计单位时间内的读取次数,最终汇总所有线程结果计算总带宽。
2. 无依赖批量随机访问
打破单指令依赖链,利用CPU乱序执行和内存级并行(MLP)能力,一次性发起多个独立内存请求:
- 预先生成覆盖全内存空间的随机地址数组,确保地址无依赖关系。
- 批量发起加载指令,比如一次性发起8-16个独立
LOAD操作,让CPU乱序执行这些指令,同时向内存发送多个请求。示例伪代码:// 预先生成随机地址数组addr[],大小远大于CPU缓存 for (int i = 0; i < 16; i++) { __asm__ volatile("mov (%0), %%rax" : : "r"(addr[i]) : "rax"); } - 需预先用大内存块冲刷CPU缓存,确保所有读取请求直接访问主存。
3. 强制非缓存访问
避免指针追踪的数据进入CPU缓存,确保测试的是主存带宽而非缓存带宽:
- x86架构使用
MOVNTDQA(非临时对齐读取)指令,ARM架构使用LDNP等非缓存加载指令,强制绕过CPU缓存。 - 工作集大小需远大于CPU三级缓存容量(比如16GB以上,根据实际缓存大小调整),彻底杜绝数据被缓存的可能。
4. 地址交错分布优化
现代内存多为多通道架构,随机地址分布不均会导致部分通道闲置,需确保地址均匀覆盖所有通道:
- 先查询目标系统的内存通道交错规则(比如按64KB或256KB块交错分配地址)。
- 生成随机地址时,确保地址均匀分布在所有通道的地址范围内,充分利用多通道带宽。
结果验证
- 先计算内存理论带宽:
内存频率 × 总线宽度 × 通道数 / 8,将测试结果与理论值对比,判断是否接近极限。 - 通过CPU性能监控计数器(比如x86的
UNC_M_CAS_COUNT.READ事件)监控内存控制器利用率,确保利用率接近100%。 - 调整线程数或批量请求大小,直到内存带宽不再提升,确认已突破CPU瓶颈。
内容的提问来源于stack exchange,提问作者Frontier_Setter
相关产品推荐
相关产品推荐

