I have a parallel code that can be reduced to basically:
#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);
}
I would like to modernize that code by using the c++17 parallel algorithms. Unfortunately, I'm having trouble in rewriting such a simple piece of code.
An option would be using 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]);
});
}
This works but is considerably more verbose and, worse, I don't think it is compliant with the
standard because boost::counting_iterator
is a stashing iterator and, therefore, does not
meet the Cpp17ForwardIterator requirements.
Is it possible to write the above code as concisely as with OpenMP, while satisfying the constraints of the standard on parallel algorithms?
counting_iterator
is no ForwardIterator? Afaik ForwardIterator is just the minimum that is needed to makefor_each
work, not more – Aboriginecounting_iterator
returns by value. – Kearyreference
typedef as beingconst Incrementable&
, andoperator*
does returnreference
– VirgelIt1->ObjPtr->Calculate(*It2);
stem from consecutiveKey
values that compare equal, but only in the container part thatIt1
hasn't passed yet, plus object pairings behind the iterators will be used multiple times for more than two equal consecutive keys. – AmadorForwardIterator
s must return areference
andcounting_iterator
does not. See also point 6 "Ifa
andb
are both dereferenceable, thena == b
if and only if*a
and*b
are bound to the same object" – KearyKeyObjPtrVec
is sorted byKey
. The loop simply tests pairs ofKeyObjPtr
with equalKey
. I don't think is complicated at all. – Keary