使用自己的迭代器并行执行



我有一些简单的代码,通过查找除法器来检查大数的素性。我尝试通过使用具有并行执行策略的std::none_of函数来并行执行:

BigInt isPrime(const BigInt &x) {
BigInt i(0);
BigIntRangeIterator range(2, x);
// If use std::vector, works fine:
// std::vector<BigInt> range;
// for (BigInt i(2); i < x; i = i + BigInt(1)) range.push_back(i);
std::mutex m;
std::none_of(std::execution::par_unseq, range.begin(), range.end()
, [&](auto y) {
if (x % y == BigInt(0)) {
const std::lock_guard<std::mutex> lock(m);
i = y;
return true;
}
return false;
}
);
return i;
}

如果数字是素数,函数isPrime返回零,否则返回x的任何除法器。

为了不浪费存储除法器范围的空间,我为BigNum实现了自己的迭代器,它只存储开始、结束和当前值,并将其递增:

/* Header file */
class BigIntRangeIterator
: public std::iterator
< std::forward_iterator_tag
, BigInt
, BigInt
, const BigInt*
, BigInt&
>
{
public:
BigIntRangeIterator(): _begin(0), _end(0), _it(0){}
BigIntRangeIterator(const BigInt &b, const BigInt &e)
: _begin(b), _end(e), _it(b) {}
bool operator!=(const BigIntRangeIterator &rhs) const;
bool operator==(const BigIntRangeIterator &rhs) const;
BigInt const & operator*() const;
BigIntRangeIterator const & operator++();
BigIntRangeIterator begin() const;
BigIntRangeIterator end() const;
private:
BigInt _begin, _end, _it;
};
/*CPP file */
bool BigIntRangeIterator::operator!=(const BigIntRangeIterator &rhs) const {
return _it != rhs._it;
}
bool BigIntRangeIterator::operator==(const BigIntRangeIterator &rhs) const {
return _it == rhs._it;
}
BigInt const & BigIntRangeIterator::operator*() const {
return _it;
}
BigIntRangeIterator const & BigIntRangeIterator::operator++() {
_it = _it + BigInt(1);
return *this;
}
BigIntRangeIterator BigIntRangeIterator::begin() const {
return BigIntRangeIterator(_begin, _end);
}
BigIntRangeIterator BigIntRangeIterator::end() const {
BigIntRangeIterator ret(_begin, _end);
ret._it = _end;
return ret;
}

我的问题是,这个函数总是在一个线程中运行,忽略了并行执行策略。它为什么这么做?

经过长时间的搜索,我发现具有并行执行策略的none_of函数只能与随机访问迭代器并行工作。如果自己的迭代器只是正向迭代器,它总是按顺序运行。

最新更新