并行分配给std :: vector <std :: vector <double >>

时间:2019-04-11 01:39:00

标签: c++ vector openmp matrix-multiplication

我有一些串行代码,用矩阵向量乘以分别表示为std::vector<std::vector<double>>std::vector<double>的矩阵:

void mat_vec_mult(const std::vector<std::vector<double>> &mat, const std::vector<double> &vec,
                  std::vector<std::vector<double>> *result, size_t beg, size_t end) {
  //  multiply a matrix by a pre-transposed column vector; returns a column vector
  for (auto i = beg; i < end; i++) {
    (*result)[i] = {std::inner_product(mat[i].begin(), mat[i].end(), vec.begin(), 0.0)};
  }
}

我想使用OpenMP并行化它,我正在尝试学习。从here开始,我了解了以下内容:

void mat_vec_mult_parallel(const std::vector<std::vector<double>> &mat, const std::vector<double> &vec,
                  std::vector<std::vector<double>> *result, size_t beg, size_t end) {
  //  multiply a matrix by a pre-transposed column vector; returns a column vector
    #pragma omp parallel
    {
        #pragma omp for nowait
          for (auto i = beg; i < end; i++) {
            (*result)[i] = {std::inner_product(mat[i].begin(), mat[i].end(), vec.begin(), 0.0)};
          }
    }
}

这种方法没有带来任何提速;在选择正确的OpenMP指令方面,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

有几件事可以解释您缺乏看到性能改进的原因。最有前途的是:

  1. 您没有在编译器级别激活OpenMP支持。好吧,从评论来看,情况似乎并非如此,因此可以为您排除这种情况。我仍在提及它,因为这是一个非常常见的错误,因此最好提醒一下这是必需的。
  2. 测量时间的方式:当心CPU时间与经过时间。例如,请参见this answer,以了解如何正确测量经过的时间,因为这是您希望减少的时间。
  3. 您的代码受内存限制的事实:通常,矩阵矩阵乘法是利用CPU功能的亮点。但是,这并不是魔术般的。该代码必须针对该目标进行调整。最早应用的一种调整技术是平铺/缓存阻止。目的是在缓存中最大化(重用)数据,而不是将其提取到中央内存中。从您的代码中可以看到,该算法的作用恰恰相反,因此它从内存中流式传输数据进行处理,完全忽略了重用潜力。因此,您受内存限制,在这种情况下,对不起,但是OpenMP并不能为您提供太多帮助。例如,请参见this answer以了解原因。

这些并不是可以解释某些缺乏可伸缩性的唯一原因,但是鉴于您提供的信息有限,我认为它们是最有可能的罪魁祸首。