【问题标题】:Best way to Parallelizing matrix vector multiplication using openMP使用openMP并行化矩阵向量乘法的最佳方法
【发布时间】:2021-12-20 17:23:32
【问题描述】:

我有以下代码,我使用 openMP 并行化了这些代码:

#pragma omp parallel shared(matrix, result, vector) private(i, j)
  {
#pragma omp for schedule(static)
    for (i = 0; i < n; i++)
    {
      for (j = 0; j <= i && j < n; k++)
      {

        result[i] += matrix[i * n + j] * vector[j];
      }
    }
  }

我已将上述 pragma 指令添加到 for 循环中,该循环计算矩阵和列向量的乘积。它确实加快了速度。但是,是否有更有效的方法来使用 OpenMP 加快速度? 我尝试了不同类型的计划静态、动态、运行时、引导、自动。对于大至 30000 x 30000 的矩阵,静态和自动似乎给出了最好的结果。如果 j>i,矩阵具有 matrix[i][j]=0 的属性

【问题讨论】:

  • for (j = 0; j &lt;= i &amp;&amp; j &lt; n; k++) -> for (j = 0; j &lt;= i; j++) ?
  • 请添加包含循环的完整函数。确保 result 具有 restrict 限定符
  • 在外循环中提前获取你的矩阵行。 const T* row = matrix + i*n; 然后在内循环中访问row[j]。图像处理中的同类优化。除非优化器赶上来,否则应该会有所作为。

标签: c optimization parallel-processing openmp


【解决方案1】:
  1. 如果您使用局部临时变量对j 循环的结果求和,可能有助于编译器优化代码。您的编译器也可以这样做,但如果不这样做,它会快得多。

  2. 始终在所需的最小范围内使用您的变量,这也有助于编译器进行优化。

  3. 确保您的编译器可以有效地向量化您的代码:使用适当的编译器标志,如果您使用指针,则通过使用 restrict 关键字或添加 #pragma ivdep(英特尔编译器)告诉编译器没有循环携带依赖项,#pragma gcc ivdep (GCC), #pargma loop(ivdep) (MSVC), #pragma clang loop vectorize(assume_safety) (clang) 在内循环之前。

因此,您的代码应如下所示:

#pragma omp parallel for shared(matrix, result, vector) schedule(static)
    for (size_t i = 0; i < n; i++)
    {
      double sum=0;
      #pragma GCC ivdep
      for (size_t j = 0; j <= i; j++) //as suggested by @tstanisl
      {
        sum += matrix[i * n + j] * vector[j];
      }
      result[i] += sum;
    }
  }

【讨论】:

    猜你喜欢
    • 2017-09-14
    • 2021-07-20
    • 2021-02-06
    • 2018-08-24
    • 1970-01-01
    • 2018-12-05
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多