简体   繁体   English

C ++ 17:如何在并行STL中获取工作项的索引

[英]C++17: How to get the index of a work item in parallel STL

Is there a way to know an ID/index of a work item in parallel algorithms? 有没有办法知道并行算法中工作项的ID /索引?

That would be useful for example in generating iota: 例如,在生成iota时这将很有用:

std::vector<int> vec(max_size);
std::for_each(std::execution::par, vec.begin(), vec.end(), 
   [](int& elem) {
    elem = work_item_index;
});

but how to compute that work_item_index value efficiently? 但是如何有效地计算该work_item_index值?

EDIT: This approach is not guaranteed to work, as the element identity (ie the address) cannot be relied upon in parallel execution. 编辑:这种方法不能保证能正常工作,因为不能并行执行依赖元素标识(即地址)。

A correct solution is to tie the iterator range with a range of indices, as shown in Caleth's answer. 正确的解决方案是将迭代器范围与索引范围绑定在一起,如Caleth的答案所示。

You can use pointer arithmetic: 您可以使用指针算法:

 
 
 
  
  int* beg = vec.data(); std::for_each(std::execution::par, vec.begin(), vec.end(), [beg](int& elem) { elem = &elem - beg; });
 
  

Obviously, this only works for containers which store the elements contiguously. 显然,这仅适用于连续存储元素的容器。

You operate on a range that includes an index. 您在包含索引的范围内进行操作。

std::vector<int> vec(max_size);
auto indexed_vec = ranges::view::zip(vec, ranges::view::indices(vec));
std::for_each(std::execution::par, indexed_vec.begin(), indexed_vec.end(), 
   [](std::tuple<int&, int> elem) {
    std::get<0>(elem) = std::get<1>(elem);
});

Actually it's not standardized. 实际上,它不是标准化的。 It depends on parallel engine that is used for algorithms' parallelization. 它取决于用于算法并行化的并行引擎。 For example, omp_get_thread_num() for OpenMP. 例如,用于OpenMP的omp_get_thread_num()

However, if you just want to get index of current processing element of vector you can use counting_iterator . 但是,如果只想获取向量的当前处理元素的索引,则可以使用counting_iterator As soon as it's also non-standardized feature, you can use it from libraries: Boost , TBB , Intel's Parallel STL 一旦它也是非标准化功能,您就可以从以下库中使用它: BoostTBBIntel的Parallel STL

std::vector<int> vec(max_size);
auto first = vec.begin();
std::for_each(std::execution::par, counting_iterator<int>(0), counting_iterator<int>(max_size), 
   [first](int& work_item_index) {
    first[work_item_index] = work_item_index;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM