由于没有基于索引的parallel for algorithm在 c++17 , 我想知道 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
modelsAdvanceable
, theniterator_category
israndom_access_iterator_tag
.(1.2) — Otherwise, if
I
modelsDecrementable
, theniterator_category
isbidirectional_iterator_tag
.(1.3) — Otherwise, if
I
modelsIncrementable
, theniterator_category
isforward_iterator_tag
.(1.4) — Otherwise,
iterator_category
isinput_iterator_tag
.
上面的代码是否正确?使用 iota_view
是否有任何性能损失?这条路?
编辑:我用 range-v3 做了一些测试, cmcstl2和英特尔的 PSTL .
使用 range-v3,上面的例子无法用 GCC 8 编译。编译器提示 begin
和 end
有不同的类型:
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_view
在 for_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
, orForwardIterator2
, 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/