使用OpenMP并行实现C语言矩阵乘法仅计算对角线元素问题
OpenMP矩阵乘法仅计算对角线元素的问题修复
你的代码核心错误在于错误绑定线程ID(tid)与矩阵行索引,且omp for的循环分配逻辑和矩阵C的赋值逻辑不匹配,导致仅C[tid][i]位置被计算,其余元素未初始化,最终出现随机值。
问题具体分析
- 你设置了N个线程,
omp for会将i的循环迭代分配给不同线程,但你始终用tid作为C的行索引、i作为列索引,这导致每个线程仅计算C[tid][i]单个位置,而非一整行。 - 以N=2为例:线程0可能处理
i=0,计算C[0][0];线程1处理i=1,计算C[1][1]。而C[0][1]、C[1][0]从未被赋值,内存中保留随机初始值。
修正后的代码
# include <stdio.h> # include <omp.h> int main(void){ int N, element; int i, j, k; scanf("%d", &N); // 矩阵维度 int A[N][N]; // 矩阵A int B[N][N]; // 矩阵B int C[N][N]; // 结果矩阵C = A*B // 输入矩阵A元素 for(i = 0; i < N; i++){ for(j = 0; j < N; j++){ scanf("%d", &element); A[i][j] = element; } } // 输入矩阵B元素 for(i = 0; i < N; i++){ for(j = 0; j < N; j++){ scanf("%d", &element); B[i][j] = element; } } omp_set_num_threads(N); // 设置线程数量 #pragma omp parallel default(none) shared(A, B, C, N) private(i, j, k) { #pragma omp for for (i = 0; i < N; i++){ // 每个线程负责计算矩阵C的一行 for (j = 0; j < N; j++){ // 计算该行的每一列 C[i][j] = 0; for (k = 0; k < N; k++){ // 矩阵乘法累加计算 C[i][j] += A[i][k] * B[k][j]; } } } } // 打印结果矩阵C for(i = 0; i < N; i++){ for(j = 0; j < N; j++){ printf("%d ", C[i][j]); } printf("\n"); } return(0); }
关键修正点
- 移除不必要的
tid变量:omp for会自动将行索引i分配给各个线程,无需手动绑定线程ID与行。 - 调整循环结构:外层循环处理行
i,中间循环处理列j,内层循环完成矩阵乘法的累加计算,完全符合矩阵乘法公式C[i][j] = sum(A[i][k] * B[k][j])。 - 每个线程负责完整的一行计算,确保矩阵C的所有元素都被正确初始化和赋值。
测试验证
当N=2,矩阵A={{1,2},{3,4}}、B={{1,2},{3,4}}时,修正后的代码会输出正确结果:
7 10 15 22
内容的提问来源于stack exchange,提问作者Diego Bravo
相关产品推荐
相关产品推荐

