【问题标题】:Speed Up Matrix Multiplication with OpenMP and Block Method: Can I Do Better?使用 OpenMP 和块法加速矩阵乘法:我能做得更好吗?
【发布时间】:2016-09-14 10:29:42
【问题描述】:

这是我写的代码:

#include <omp.h>
void matrix_multi(int c[][TSIZE], int a[][TSIZE], int b[][TSIZE])
{
   int B=8;

  int i, j, k,i1,j1,k1;
#pragma omp parallel for private(i,j,k,i1,j1,k1) schedule(auto) collapse(3)
  for (i=0; i<TSIZE; i+=B)
    for (j=0; j<TSIZE; j+=B)
      for (k=0; k<TSIZE; k+=B)
        for (i1=i;i1<i+B;i1++)
          for (j1=j;j1<j+B;j1++)
            {
              int sum=0;
              for (k1=k;k1<k+B;k1++)
                {
                  sum+=a[i1][k1]*b[k1][j1];
                }
              c[i1][j1]+=sum;
            }

}

我的问题是:我可以通过对三个内部循环进行进一步操作来获得更好的性能吗?

【问题讨论】:

  • 您测量过您获得的性能吗?对于矩阵乘法,您可以与理论峰值性能进行比较。
  • 我不相信这段代码是正确的:collapse(3) 指令平行于 3 个索引 ijk。这意味着您可以保证两个不同的线程不会处理相同的i,j,k 三元组。但是,对于两个线程,您很可能拥有相同的 i,j 对和不同的 k。这将导致更新c[i1][j1]...
  • This particular course video 完全致力于提高矩阵乘法的速度。
  • 我强烈建议你使用这个 stackExchange,专门用于这些情况:codereview.stackexchange.com

标签: c parallel-processing openmp matrix-multiplication


【解决方案1】:

线性代数是计算机执行的最常见的运算之一。在游戏和图形库中,这是最常见的操作。它已经过大量研究和优化,整个研究小组都致力于此。

如果您关心速度,您应该使用BLAS 库执行矩阵乘法。 BLAS 库将针对以下方面进行优化:

  • 通过在块中执行矩阵乘法而不是在整个矩阵上循环来最大限度地减少缓存未命中
  • 针对计算机的缓存大小优化块大小
  • 如果计算机/CPU 有多个缓存级别,请使用多个优化的块大小级别
  • 如果 CPU 上可用,请使用 SIMD 指令

请注意,并行化不在列表中。这是因为在今天的计算机中,内存访问比 CPU 慢。由于上下文切换的开销,您将看到 openmp 的性能更差

【讨论】:

    【解决方案2】:

    看来你离完全优化还很远。你试过循环展开、循环反转等吗?

    您可以参考以下链接逐步优化矩阵乘法。

    http://wiki.cs.utexas.edu/rvdg/HowToOptimizeGemm/

    【讨论】:

    • 我研究了一天,做了很多实验。不幸的是,我认为利用 openMP int 这种方法很难(或超出我的能力)。它的性能比使用 openMP 的代码差一点。
    • @HuanmingSong 链接正在优化单线程GEMM。借助优化的单线程 GEMM,您可以使用 OpenMP 提高多核 CPU 的性能。
    猜你喜欢
    • 2021-02-28
    • 2017-09-14
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    • 2017-09-11
    • 2015-12-26
    相关资源
    最近更新 更多