我有一些串行代码,可以将矩阵 vector 与表示为 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 指令,我将不胜感激。
最佳答案
有几件事可以解释您没有看到性能改进。最有前途的是这些:
- 您没有在编译器级别激活 OpenMP 支持。嗯,从评论来看,好像不是这样,所以可以给你排除这个。我仍然提到它,因为这是一个很常见的错误,所以最好提醒一下这是必要的。
- 衡量时间的方式:注意 CPU 时间与运行时间。参见 this answer例如,查看如何正确测量耗时,因为这是您希望看到的时间减少的时间。
- 您的代码受内存限制这一事实:通常情况下,矩阵-矩阵乘法是可以充分利用 CPU 能力的代码类型。然而,这并不是靠魔法出现的。必须针对该目标调整代码。最先应用的调优技术之一是平铺/缓存阻塞。目的是在缓存内存中最大限度地(重新)使用数据,而不是将其提取到中央内存。从我在您的代码中看到的情况来看,该算法的作用恰恰相反,因此它从内存中流式传输数据进行处理,完全忽略了重用的可能性。所以你是内存限制,在这种情况下,抱歉,OpenMP 帮不了你太多。参见 this answer例如,看看为什么。
这些并不是可以解释某些缺乏可扩展性的唯一原因,但鉴于您提供的信息有限,我认为它们是最有可能的罪魁祸首。
关于c++ - 并行分配给 std::vector<std::vector<double>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55623474/