c ++ как элегантно использовать параллельное выполнение с ++ 17 с циклом for, который считает целое число?

Я могу

std::vector a; a.reserve(1000); for(int i=0; i<1000; i++) a.push_back(i); std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int i) { ... do something based on i ... }); 

но есть ли более элегантный способ 9X_parallel создания распараллеленной версии for (int 9X_parallel i = 0; i

11
0
4
Общее количество ответов: 4

Ответ #1

Ответ на вопрос: c ++ как элегантно использовать параллельное выполнение с ++ 17 с циклом for, который считает целое число?

Вы можете использовать std::generate для создания вектора 9X_parallelism {0, 1, ..., 999}

std::vector v(1000); std::generate(v.begin(), v.end(), [n = 0] () mutable { return n++; }); 

Существует перегрузка, которая принимает 9X_cpp ExecutionPolicy, поэтому вы можете изменить приведенное 9X_parallelization выше на

std::vector v(1000); std::generate(std::execution::par, v.begin(), v.end(), [n = 0] () mutable { return n++; }); 

12
1

  • boost :: counting_range с ...

Ответ #2

Ответ на вопрос: c ++ как элегантно использовать параллельное выполнение с ++ 17 с циклом for, который считает целое число?

Хотя я не могу предложить способ избежать 9X_c++1z заполнения вектора, я могу порекомендовать 9X_parallel-computing использовать функцию std::iota() как (возможно) наиболее 9X_c++17 эффективный / элегантный способ заполнить 9X_parallel-computing его увеличивающимися целыми числами:

std::vector a(1000); std::iota(std::begin(a), std::end(a), 0); std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int i) { // ... do something based on i ... }); 

Сложность 9X_parallelism std::iota - это в точности last - first приращения и присваивания, тогда 9X_c++1z как функция std::generate имеет сложность last - first вызовы g() и задания. Даже 9X_cpp если бы достойный компилятор встроил простую 9X_parallelism лямбда-функцию приращения для g, синтаксис 9X_parallel iota был бы значительно проще, IMHO.

9
0

Ответ #3

Ответ на вопрос: c ++ как элегантно использовать параллельное выполнение с ++ 17 с циклом for, который считает целое число?

VisualC++ предоставляет богатую среду параллельного 9X_parallel-computing программирования, среду выполнения с параллелизмом 9X_c++1z ConCRT.
Вы можете использовать OpenMP, который 9X_parallelism является открытым стандартом, но также доступен 9X_c++1z в ConCRT. Как описано в wikipedia, это embarrassingly parallel, следующий 9X_parallel код должен создать 1000 потоков:

#include ... #pragma omp parallel for for(int s = 0; s < 1000; s++) { for(int i = 0; i < s; i++) ... do something parallel based on i ... } 

Директивы 9X_parallelization #pragma omp игнорируются, если параметр 9X_parallel-processing компилятора / openmp не указан. На самом 9X_parallelism деле я не понимаю роль вашего вектора, поэтому 9X_parallel пропустил его. Также мне непонятна причина 9X_c++1z замены стандартного for на любой for_each и работа 9X_cxx с сохраненными индексами, поскольку цикл 9X_c++17 for делает это очень хорошо.
Или вы можете 9X_c++ использовать специальную библиотеку Microsoft 9X_parallelization PPL. Следующий код также создает 1000 потоков, генерируя 9X_parallelization индексы от 0 до 999 включительно и передавая 9X_c++17 параллельную процедуру как переменную s:

#include ... using namespace concurrency; parallel_for(0, 1000, [&](int s) { for(int i = 0; i < s; i++) ... do something parallel based on i ... }); 

Для 9X_c++1z тяжелых параллельных вычислений в среде 9X_parallel-programming выполнения с параллелизмом также доступен 9X_parallel AMP. AMP выполняет параллельные процедуры 9X_parallel-processing на GPU, а не на CPU.

4
0

Ответ #4

Ответ на вопрос: c ++ как элегантно использовать параллельное выполнение с ++ 17 с циклом for, который считает целое число?

Вот два способа сделать это без предварительного 9X_c++17 заполнения вектора только для хранения последовательности 9X_parallelism целых чисел.

  1. Вы можете сделать это с помощью Boost.counting_range (или 9X_c++17 напрямую с помощью Boost.counting_iterator, как вам удобнее) ... хотя 9X_parallel-computing удачи вам узнать, как прочитать документацию.

     auto range = boost::counting_range(0,1000); std::for_each(std::execution::par_unseq, range.begin(), range.end(), [&](int i) { // ... do something based on i ... }); 
  2. Если 9X_parallel-programming вы не хотите включать Boost, мы можем написать 9X_c++ простую версию напрямую.

    Без извинений за 9X_parallel-computing то, что вы собрали вместе iota и iterator вместо того, чтобы 9X_parallel-programming придумать достойное имя, приведенное ниже 9X_parallel-programming позволит вам написать что-то похожее на 9X_parallelism версию Boost выше:

     std::for_each(std::execution::par_unseq, ioterable(0), ioterable(1000), [&](int i) { // ... do something based on i ... } ); 

    Вы можете увидеть, сколько 9X_parallel-processing шаблонов вы сэкономите, используя для этого 9X_cxx Boost:

     template struct ioterable { using iterator_category = std::input_iterator_tag; using value_type = NumericType; using difference_type = NumericType; using pointer = std::add_pointer_t; using reference = NumericType; explicit ioterable(NumericType n) : val_(n) {} ioterable() = default; ioterable(ioterable&&) = default; ioterable(ioterable const&) = default; ioterable& operator=(ioterable&&) = default; ioterable& operator=(ioterable const&) = default; ioterable& operator++() { ++val_; return *this; } ioterable operator++(int) { ioterable tmp(*this); ++val_; return tmp; } bool operator==(ioterable const& other) const { return val_ == other.val_; } bool operator!=(ioterable const& other) const { return val_ != other.val_; } value_type operator*() const { return val_; } private: NumericType val_{ std::numeric_limits::max() }; }; 
  3. Для потомков и в случае, если вы сможете 9X_cpp использовать C++ 20 в будущем, предпочтительнее 9X_parallel-computing будет std::ranges::iota_view там, где это возможно.

3
2

  • На самом деле, может быть, этого достаточно. В документе не отображается оператор `operator ==`, который вам нужно использовать для основного д ...