问题描述
考虑:
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
:
To express similar code with the C++17 parallel algorithms, the solution I found so far is to use the two input ranges version of 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范围元素进行操作)。
which I don't like at all because it bypasses the +=
operator of my types and in my real use case leads to much more verbose (4 times longer) code than the original OpenMP code (I cannot just use std::plus
because I have to first make an operation on the RHS range elements).
还有另一个我监督的算法吗? ?
Is there another algorithm that I oversight?
还要注意,如果我使用 ranges :: zip
,则代码不会在GCC 9中并行运行因为如果 iterator_category
至少不小于 forward_iterator
,则PSTL后端会回落到t顺序算法:。
Note also that if I use ranges::zip
the code won't run in parallel in GCC 9 because if iterator_category
is not at least forward_iterator
the PSTL back-end falls back to the sequential algorithm: https://godbolt.org/z/XGtPwc.
推荐答案
您是否尝试过tbb :: zip_iterator()?
其 iterator_category
是 random_access_iterator
。
Have you tried tbb::zip_iterator (https://www.threadingbuildingblocks.org/docs/help/reference/iterators/zip_iterator.html)?Its iterator_category
is 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); });
这篇关于将向量元素和分配给另一个元素的并行算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!