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

Parallel execution with own iterator

我有一些简单的代码可以通过查找除法器来检查大数的素性。我尝试通过使用具有并行执行策略的 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 returns 零,如果数字是质数,否则 returns x 的任何除数。

为了不浪费 space 来存储分隔符的范围,我为 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 函数只能与随机访问迭代器并行工作。如果自己的迭代器只是前向迭代器,它总是运行顺序。