gpt4 book ai didi

c++ - 使用 c++17 算法并行化一个简单的循环

转载 作者:行者123 更新时间:2023-12-01 12:34:45 27 4
gpt4 key购买 nike

我有一个并行代码,基本上可以简化为:

#include <algorithm>
#include <vector>

struct TKeyObjPtr;

class TObj
{
public:
virtual void Calculate(TKeyObjPtr const &) = 0;
};

struct TKeyObjPtr
{
int Key;
TObj *ObjPtr;
};

void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
#pragma omp parallel for
for (auto It1= KeyObjPtrVec.begin(); It1!=KeyObjPtrVec.end(); ++It1)
for (auto It2= It1+1; It2!=KeyObjPtrVec.end() && It2->Key==It1->Key; ++It2)
It1->ObjPtr->Calculate(*It2);
}

我想通过使用 来更新该代码并行算法。
不幸的是,我在重写这样一段简单的代码时遇到了麻烦。

一个选项是使用 boost::counting_iterator :
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
std::for_each(std::execution::par_unseq,
boost::counting_iterator<std::size_t>(0u),
boost::counting_iterator<std::size_t>(KeyObjPtrVec.size()),
[&KeyObjPtrVec](auto i)
{
for (auto j= i+1; j<KeyObjPtrVec.size() && KeyObjPtrVec[j].Key==KeyObjPtrVec[i].Key; ++j)
KeyObjPtrVec[i].ObjPtr->Calculate(KeyObjPtrVec[j]);
});
}

这有效但更冗长,更糟糕的是,我认为它不符合
标准是因为 boost::counting_iterator是一个隐藏迭代器,因此不
遇见 Cpp17ForwardIterator requirements .

是否可以像使用 OpenMP 一样简洁地编写上述代码,同时满足
标准对并行算法的限制?

最佳答案

迭代器可以按值分配。分配的迭代器是一个拷贝,当原始分配源增加时不会前进。因此你可以简单地

template<typename I>
void calculate(const I It1, const I It2) {
// This statement can also run at any time later. The iterators will point
// how they were when the calculate(...) was called.
It1->ObjPtr->Calculate(*It2);
}

void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec) {
for (auto It1 = KeyObjPtrVec.begin(); It1 != KeyObjPtrVec.end(); ++It1)
for (auto It2 = It1 + 1; It2 != KeyObjPtrVec.end() &&
It2->Key == It1->Key; ++It2)
calculate(It1, It2);
}
不幸的是,C++17 并不是一个专用的并行编程平台。您需要安排一个有意义的大小和任务队列的线程池,他们可以从中挑选任务。任务记录只能保存这两个分配为结构字段的迭代器。您还需要一种机制来知道所有并行处理何时完成,以便您可以继续。

关于c++ - 使用 c++17 算法并行化一个简单的循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54522037/

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