将向量的元素求和分配给另一个向量的元素的并行算法
Parallel algorithm to sum-assign the elements of a vector to the elements of another one
考虑:
std::vector<double> u, v;
#pragma omp parallel for
for (std::size_t i = 0u; i < u.size(); ++i)
u[i] += v[i];
为了用 C++17 并行算法表达类似的代码,我目前找到的解决方案是使用 std::transform
的两个输入范围版本:
std::transform(std::execution::par_unseq,
std::begin(u), std::end(u), std::begin(v), std::begin(u),
std::plus())
我根本不喜欢它,因为它绕过了我的类型的 +=
运算符,并且在我的实际用例中导致比原始 OpenMP 代码更冗长(长 4 倍)的代码(我不能只使用 std::plus
因为我必须先对 RHS 范围元素进行操作。
还有其他我忽略的算法吗?
另请注意,如果我使用 ranges::zip
,代码将不会在 GCC 9 中并行 运行,因为如果 iterator_category
至少 forward_iterator
PSTL 返回-end 回到顺序算法:https://godbolt.org/z/XGtPwc.
您尝试过tbb::zip_iterator(https://www.threadingbuildingblocks.org/docs/help/reference/iterators/zip_iterator.html)吗?
它的 iterator_category
是 random_access_iterator
.
所以代码看起来像
auto zip_begin = tbb::make_zip_iterator(std::begin(u), std::begin(v));
std::for_each(par_unseq, zip_begin, zip_begin + u.size(),
[](auto &&x) { std::get<0u>(x) += std::get<1u>(x); });
考虑:
std::vector<double> u, v;
#pragma omp parallel for
for (std::size_t i = 0u; i < u.size(); ++i)
u[i] += v[i];
为了用 C++17 并行算法表达类似的代码,我目前找到的解决方案是使用 std::transform
的两个输入范围版本:
std::transform(std::execution::par_unseq,
std::begin(u), std::end(u), std::begin(v), std::begin(u),
std::plus())
我根本不喜欢它,因为它绕过了我的类型的 +=
运算符,并且在我的实际用例中导致比原始 OpenMP 代码更冗长(长 4 倍)的代码(我不能只使用 std::plus
因为我必须先对 RHS 范围元素进行操作。
还有其他我忽略的算法吗?
另请注意,如果我使用 ranges::zip
,代码将不会在 GCC 9 中并行 运行,因为如果 iterator_category
至少 forward_iterator
PSTL 返回-end 回到顺序算法:https://godbolt.org/z/XGtPwc.
您尝试过tbb::zip_iterator(https://www.threadingbuildingblocks.org/docs/help/reference/iterators/zip_iterator.html)吗?
它的 iterator_category
是 random_access_iterator
.
所以代码看起来像
auto zip_begin = tbb::make_zip_iterator(std::begin(u), std::begin(v));
std::for_each(par_unseq, zip_begin, zip_begin + u.size(),
[](auto &&x) { std::get<0u>(x) += std::get<1u>(x); });