You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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);
}

关键修正点

  1. 移除不必要的tid变量:omp for会自动将行索引i分配给各个线程,无需手动绑定线程ID与行。
  2. 调整循环结构:外层循环处理行i,中间循环处理列j,内层循环完成矩阵乘法的累加计算,完全符合矩阵乘法公式C[i][j] = sum(A[i][k] * B[k][j])。
  3. 每个线程负责完整的一行计算,确保矩阵C的所有元素都被正确初始化和赋值。

测试验证

当N=2,矩阵A={{1,2},{3,4}}、B={{1,2},{3,4}}时,修正后的代码会输出正确结果:

7 10 
15 22 

内容的提问来源于stack exchange,提问作者Diego Bravo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:53:09