gpt4 book ai didi

c++ - 在并行算法中使用 ranges::view::iota

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:32 26 4
gpt4 key购买 nike

由于没有基于索引的parallel for algorithm , 我想知道 ranges::view::iota可以与std::for_each结合使用模仿那个。即:

using namespace std;

constexpr int N= 10'000'000;
ranges::iota_view indices(0,N);
vector<int> v(N);

for_each(execution::par_unseq,indices.begin(),indices.end(),[&](int i) { v[i]= i; });

iota_view似乎为适当的类型提供随机访问([range.iota.iterator]):

iota_view<I, Bound>::iterator::iterator_category is defined as follows:

(1.1) — If I models Advanceable, then iterator_category is random_access_iterator_tag.

(1.2) — Otherwise, if I models Decrementable, then iterator_category is bidirectional_iterator_tag.

(1.3) — Otherwise, if I models Incrementable, then iterator_category is forward_iterator_tag.

(1.4) — Otherwise, iterator_category is input_iterator_tag.

上面的代码是否正确?使用 iota_view 是否有任何性能损失?这条路?


编辑:我用 range-v3 做了一些测试, cmcstl2和英特尔的 PSTL .

使用 range-v3,上面的例子无法用 GCC 8 编译。编译器提示 beginend有不同的类型:

deduced conflicting types for parameter ‘_ForwardIterator’ (‘ranges::v3::basic_iterator<ranges::v3::iota_view<int, int> >’ and ‘ranges::v3::default_sentinel’)

使用 cmcSTL2 代码可以干净地编译,但不能并行运行。在我看来,它会退回到顺序版本,可能是因为前向迭代器的要求在某种程度上未得到满足(https://godbolt.org/z/yvr-M2)。

有一个有点相关的 PSTL 问题 ( https://github.com/intel/parallelstl/issues/22 )。

最佳答案

在深入研究标准草案后,恐怕答案是否定的:使用起来并不严格符合标准ranges::iota_viewfor_each 的并行版本中。

for_each 的并行重载声明为 [alg.foreach] :

template<class ExecutionPolicy, class ForwardIterator, class Function>
void for_each(ExecutionPolicy&& exec,
ForwardIterator first, ForwardIterator last,
Function f);

另一方面,在[algorithms.requirements]我们找到约束:

If an algorithm's template parameter is named ForwardIterator, ForwardIterator1, or ForwardIterator2, the template argument shall satisfy the Cpp17ForwardIterator requirements.

正如 Billy O'Neal 在我在问题中发布的一个链接中指出的那样,ranges::iota_view::iterator 的合理实现不太可能满足“相等的迭代器引用同一对象”前向迭代器要求 [iterator.cpp17] .因此,在我看来,ranges::iota_view::iterator 不会满足 Cpp17ForwardIterator 要求,例如boost::counting_iterator

然而,在实践中我希望实现将使用 std::iterator_traits::iterator_category 来分派(dispatch)算法的适当重载,正如 PSTL 似乎所做的那样。因此,我相信 OP 中的示例代码会按预期工作。 cmcSTL2 不起作用的原因可能是使用的 iterator_category 属于 __stl2 namespace而不是 std 的。

关于c++ - 在并行算法中使用 ranges::view::iota,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51185974/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com