Предлагает ли C ++ 17 генераторы или другой встроенный способ параллельного преобразования неинстанцированной последовательности? - PullRequest
0 голосов
/ 10 ноября 2018

Я пытаюсь преобразовать последовательность чисел параллельно в C ++ 17 и сохранить результаты в векторе. Но пока я не могу найти способ представления последовательности без явного заполнения массива, например:

void transformRange(size_t N)
{
    // Want to replace nums with a generator (an iterator that is not associated with a container)
    std::vector<size_t> nums(N);
    std::iota(nums.begin(), nums.end(), 0);

    std::vector<size_t> a(N);
    std::transform(std::execution::par, nums.begin(), nums.end(), a.begin(), fun);
}

Я хочу, чтобы это было выполнимо параллельно (следовательно, std :: execute :: par), и вышеупомянутое преобразование работает параллельно, но йота - нет, и это в 3 раза больше пропускной способности памяти.

Я также открыт для получения порядкового номера из ссылки на преобразовываемое значение, но не могу понять синтаксис правильно. Что-то вроде:

void transformRange2(size_t N)
{
    std::vector<size_t> a(N);
    std::transform(std::execution::par, a.begin(), a.end(), a.begin(), [&](auto & i) {fun(&i - a.begin()); });
}

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018
template<class F, class R=std::result_of_t<F&(std::size_t)>>
std::vector<R> rangeFromIndex(F&& f, std::size_t N)
{
  std::vector<R> a(N);
  std::for_each(std::execution::par,
    a.begin(), a.end(),
    [&](auto & i) {i = fun(std::size_t(std::addressof(i) - a.data())); }
  );
}

это должно сделать это.

0 голосов
/ 11 ноября 2018

Диапазоны, не поддерживаемые контейнером (или кошмаром, называемым std::vector<bool>), не являются частью C ++ 17.

Но не отчаивайтесь, Boost предоставляет counting_iterator, именно то, что вам нужно для ленивого диапазона.

Он даже обеспечивает удобную упаковку как диапазон, используя counting_range.

...