应用Memory Bound占比过高
现象
应用执行过程中内存频繁进行随机读写,导致产生跨DIE,甚至跨片的内存访问,使应用在内存资源上的消耗大幅增加。
调优思路
使用鲲鹏DevKit系统性能分析执行HPC应用分析任务,查看内存带宽相关数据是否异常,确认后对内存的访问进行限制,加强其访问的局部性,达到减少资源消耗的目的。
操作步骤
- 准备示例源码memory_bound.c并进行编译。
1
gcc memory_bound.c -O3 -o memory_bound -fopenmp -lm
- 使用鲲鹏DevKit系统性能分析执行HPC应用分析任务。
表1 任务配置参数说明 参数
说明
分析对象
应用
应用路径
输入程序所在的绝对路径,例如本示例将代码样例放在服务器“/opt/testdemo/memory_bound”路径下。
分析类型
HPC应用分析
采集模式
OpenMP模式;本示例主要是对OpenMP的应用进行分析。
分析模式
统计分析
采样模式
Summary模式
采样时长
默认
- 查看任务结果。
发现内存带宽的各项数据中平均DRAM带宽、读带宽、写带宽都相对较高,进一步查看Top-Down各项指标,其中Memory Bound占比较高,导致了内存带宽较高的现象。
- 分析源码。
MemoryBoundBench函数内没有对内存的访问进行限制,可能会导致内存访问的随机性增加,易产生跨DIE跨片访问,增加开销。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void MemoryBoundBench(Point *pointA, double *ret, int n) { if (pointA == NULL || ret == NULL) { return; } int i,j; #pragma omp parallel for for (i = 0; i < n; i++) { ret[i] = 0.0; for (j = 0; j < n; j++) { ret[i] += pointA[i].x + pointA[j].y; } } }
- 优化源码。在源码内,对热点函数MemoryBoundBench增加cache blocking,以提升内存访问的局部性。以下方demo为例,对j限制大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
void MemoryBoundBench(Point *pointA, double *ret, int n) { if (pointA == NULL || ret == NULL) { return; } int i,j,k; for (k = 0;k < n;k += 4096){ #pragma omp parallel for for (i = 0; i < n; i++) { ret[i] = 0.0; for (j = 0; j < 4096; j++) { ret[i] += pointA[i].x + pointA[j + k].y; } } } }
- 将修改后的源码重新编译。
1
gcc memory_bound.c -O3 -o memory_bound -fopenmp -lm
- 再使用工具分析,观察Memory Bound和内存带宽数据。
优化效果
优化后,Memory Bound占比由47.8%下降至10.7%,同时内存带宽的数据由67.8G/s下降至0.3G/s,整体资源消耗降低。
图1 带宽和HPC Top-Down

父主题: 示例8:HPC应用异常指标优化分析