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
Ответ #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++; });
- 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.
Ответ #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
Ответ на вопрос: c ++ как элегантно использовать параллельное выполнение с ++ 17 с циклом for, который считает целое число?
Вот два способа сделать это без предварительного 9X_c++17 заполнения вектора только для хранения последовательности 9X_parallelism целых чисел.
-
Вы можете сделать это с помощью
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 ... });
-
Если 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() }; };
-
Для потомков и в случае, если вы сможете 9X_cpp использовать C++ 20 в будущем, предпочтительнее 9X_parallel-computing будет
std::ranges::iota_view
там, где это возможно.
- На самом деле, может быть, этого достаточно. В документе не отображается оператор `operator ==`, который вам нужно использовать для основного д ...
-
4
-
15
-
6
-
3
-
4
-
2
-
2
-
5
-
23
-
5
-
1
-
4
-
4
-
5
-
4
-
1
-
4
-
1
-
2
-
3
-
4
-
2
-
3
-
1
-
1
-
4
-
5
-
3
-
2
-
4
-
3
-
5
-
1
-
3
-
2
-
2
-
2
-
5
-
4
-
3
-
2
-
1
-
1
-
2
-
3
-
2
-
5
-
1
-
2
-
1