Openmp 和 std::vector 上的縮約

Openmp and reduction on std::vector?

本文关键字:vector std Openmp      更新时间:2023-10-16

我想使这段代码并行:

std::vector<float> res(n,0);
std::vector<float> vals(m);
std::vector<float> indexes(m);
// fill indexes with values in range [0,n)
// fill vals and indexes
for(size_t i=0; i<m; i++){
  res[indexes[i]] += //something using vas[i];
}

在本文中,建议使用:

#pragma omp parallel for reduction(+:myArray[:6])

在这个问题中,评论部分提出了同样的方法。

我有两个问题:

  1. 我不知道编译时m,从这两个示例中似乎需要。是这样吗?或者,如果我可以在这种情况下使用它,那么在以下命令#pragma omp parallel for reduction(+:res[:?])中,我必须用什么替换?m还是n
  2. for的指数相对于indexesvals而不是res,特别是考虑到reduction是在后者上完成的,这是否相关?

但是,如果是这样,我该如何解决此问题?

对特定类型的C++向量执行用户声明的约简是相当直接的:

#include <algorithm>
#include <vector>
#pragma omp declare reduction(vec_float_plus : std::vector<float> : 
                              std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<float>())) 
                    initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
std::vector<float> res(n,0);
#pragma omp parallel for reduction(vec_float_plus : res)
for(size_t i=0; i<m; i++){
    res[...] += ...;
}

1a( 在编译时不知道m不是必需的。

1b( 您不能在 std::vector s 上使用数组部分缩减,因为它们不是数组(并且std::vector::data不是标识符(。如果可能的话,你必须使用 n ,因为这是数组部分中的元素数。

2(只要你只是阅读indexesvals,就没有问题。

编辑:原来的initializer卡鲁斯更简单:initializer(omp_priv = omp_orig)。但是,如果原始副本没有充满零,则结果将是错误的。因此,我建议使用更复杂的初始值设定项,它总是创建零元素向量。

相关文章: