跨Socket带宽访问量过高
现象
应用运行时,存在因跨Socket带宽访问量远高于Socket内带宽访问量,导致资源消耗增加的现象。
调优思路
同一Socket中的内存访问消耗的资源远小于跨Socket的内存访问。因此将线程、进程进行绑核,使内存访问在同一个Socket上,就可以减少资源消耗。
操作步骤
- 准备示例源码socket_bandwidth.c并进行编译。
源码中“#define START_CORE_ID 64”的64为CPU核数,请根据实际情况修改。
gcc socket_bandwidth.c -O3 -o socket_bandwidth -lpthread -lm
- 使用鲲鹏DevKit系统性能分析执行HPC应用分析任务。
表1 任务配置参数说明 参数
说明
分析对象
应用
应用路径
输入程序所在的绝对路径,例如本示例将代码样例放在服务器“/opt/testdemo/socket_bandwidth”路径下。
分析类型
HPC应用分析
采集模式
OpenMP模式;本示例主要是对OMP的应用进行分析。
分析模式
统计分析
采样模式
Summary模式
采样时长
默认
- 查看任务报告。
观察内存带宽数据,若存在跨Socket带宽远高于Socket内带宽,资源消耗过高,继续执行4。
图1 带宽数据
- 分析源码。在源码内将进程进行绑核,在同一个Socket中进行内存访问。
#define START_CORE_ID 64 void MemBandwidth(int *arg) { set_thread_affinity(0); Point *pointA = InitPointsVector(MAX_ARRAY_SIZE); Point *pointB = InitPointsVector(MAX_ARRAY_SIZE); int cpuId = *arg; set_thread_affinity(cpuId); int i, j; double ret = 0.0; for (i = 0; i < LOOP_SIZE; i++) { for (j = 0; j < MAX_ARRAY_SIZE; j++) { ret += ComputPointDistance(&pointA[j], &pointB[j]); } } }
- 修改START_CORE_ID配置,将内存访问调整至一个Socket上。
#define START_CORE_ID 1 void MemBandwidth(int *arg) { set_thread_affinity(0); Point *pointA = InitPointsVector(MAX_ARRAY_SIZE); Point *pointB = InitPointsVector(MAX_ARRAY_SIZE); int cpuId = *arg; set_thread_affinity(cpuId); int i, j; double ret = 0.0; for (i = 0; i < LOOP_SIZE; i++) { for (j = 0; j < MAX_ARRAY_SIZE; j++) { ret += ComputPointDistance(&pointA[j], &pointB[j]); } } }
- 再次分析应用,观察优化效果。
使用1中的命令重新编译应用并运行,使用系统性能分析观察内存带宽数据。
优化效果
跨Socket带宽从4.7G/s降低至0.16G/s,跨Socket带宽大幅下降,内存访问消耗资源减少。
图2 优化后的带宽信息