Openmp 和减少 std::vector?
Openmp and reduction on std::vector?
我想让这段代码并行化:
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];
}
在this文章中建议使用:
#pragma omp parallel for reduction(+:myArray[:6])
在this问题中,评论区提出了同样的做法。
我有两个问题:
- 我在编译时不知道
m
,从这两个例子来看似乎是必需的。是这样吗?或者如果我可以在这种情况下使用它,我必须在以下命令 #pragma omp parallel for reduction(+:res[:?])
中用什么替换 ?
? m
或 n
?
for
的索引是相对于 indexes
和 vals
而不是 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
上使用数组部分缩减,因为它们不是数组(并且 std::vector::data
不是标识符)。如果可能的话,您必须使用 n
,因为这是数组部分中的元素数。
2) 只要你只读indexes
和vals
,就没有问题。
编辑:原来的 initializer
原因更简单:initializer(omp_priv = omp_orig)
。但是,如果原始副本不是全零,则结果将是错误的。因此,我建议使用更复杂的初始化程序,它总是创建零元素向量。
我想让这段代码并行化:
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];
}
在this文章中建议使用:
#pragma omp parallel for reduction(+:myArray[:6])
在this问题中,评论区提出了同样的做法。
我有两个问题:
- 我在编译时不知道
m
,从这两个例子来看似乎是必需的。是这样吗?或者如果我可以在这种情况下使用它,我必须在以下命令#pragma omp parallel for reduction(+:res[:?])
中用什么替换?
?m
或n
? for
的索引是相对于indexes
和vals
而不是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
上使用数组部分缩减,因为它们不是数组(并且 std::vector::data
不是标识符)。如果可能的话,您必须使用 n
,因为这是数组部分中的元素数。
2) 只要你只读indexes
和vals
,就没有问题。
编辑:原来的 initializer
原因更简单:initializer(omp_priv = omp_orig)
。但是,如果原始副本不是全零,则结果将是错误的。因此,我建议使用更复杂的初始化程序,它总是创建零元素向量。