OpenMP嵌套并行区域性能远低于预期问题排查
CC-NUMA系统下OpenMP嵌套并行SpMV性能异常问题
环境与实验配置
- 硬件:4节点、128核CC-NUMA系统
- 计算任务:稀疏矩阵-向量乘积(SpMV)
- OpenMP配置:
- 版本1:直接创建128个线程,通过
proc_bind(spread)分布在所有节点上,并行处理全量行数据 - 版本2:采用嵌套并行:外层创建4个线程(每个节点1个),先计算当前节点负责的行范围;内层在每个节点上创建32个线程,处理对应行范围,目的是让节点内线程写入结果向量
y的连续区域
- 版本1:直接创建128个线程,通过
- 验证:已设置
OMP_PLACES指定节点位置,通过numactl的numa_node_of_cpu(cpu)和sched_getcpu()确认线程绑定符合预期;版本2已调用omp_set_nested(1)启用嵌套并行支持
性能异常现象
- 版本1性能符合预期,但版本2的性能比版本1慢约100倍,即使将输入数据复制到每个节点(确保线程访问本地内存域数据),性能差异依然存在
- 额外调度问题:尝试静态调度时,尽管每行非零元素数量相同、迭代工作量一致,性能仍比guided调度差约70%
代码实现
int *row_idx = ...; int *col_idx = ...; double *val = ...; double *y = ...; double *x = ...; int num_rows = ...; // 版本1:创建128个线程分布在所有节点 #pragma omp parallel proc_bind(spread) num_threads(128) { #pragma omp for schedule(guided, 512) for(int i = 0; i < num_rows; i++){ double temp = 0; for(int j = row_idx[i]; j < row_idx[i + 1]; j++){ temp += val[j] * x[col_idx[j]]; } y[i] = temp; } } // 版本2:嵌套并行,先按节点拆分任务,再在节点内并行 omp_set_nested(1); // 外层:每个节点1个线程 #pragma omp parallel proc_bind(spread) num_threads(4) { // 计算当前节点负责的行范围 int id = omp_get_thread_num(); int start = num_rows / 4 * id; int end = start + (num_rows / 4); // 内层:当前节点上创建32个线程 #pragma omp parallel proc_bind(master) num_threads(32) { #pragma omp for schedule(guided, 512) for(int i = start; i < end; i++){ double temp = 0; for(int j = row_idx[i]; j < row_idx[i + 1]; j++){ temp += val[j] * x[col_idx[j]]; } y[i] = temp; } } }
内容的提问来源于stack exchange,提问作者lulle2007200
相关产品推荐
相关产品推荐

