Интересно, есть ли простой и простой способ вычисления циклов, например, для диапазонов, основанных на циклах, параллельных в C++. Как бы вы реализовали такую вещь? Из Scala я знаю, что функции map, filter и foreach, возможно, также могут выполнять эти параллели? Есть ли простой способ достичь этого на C++. Моей первичной платформой является Linux, но было бы неплохо, если бы она работала с кросс-plattform.Параллельные петли в C++
ответ
Что ваша платформа? Вы можете посмотреть OpenMP, хотя он не является частью C++. Но он широко поддерживается компиляторами.
Что касается диапазонов для петель, см., Например, Using OpenMP with C++11 range-based for loops?.
Я также видел несколько документов в http://www.open-std.org, которые указывают на некоторые попытки включить параллельные конструкции/алгоритмы в будущий C++, но не знают, каков их текущий статус.
ОБНОВЛЕНИЕ
Просто добавив некоторые иллюстративный код:
template <typename RAIter>
void loop_in_parallel(RAIter first, RAIter last) {
const size_t n = std::distance(first, last);
#pragma omp parallel for
for (size_t i = 0; i < n; i++) {
auto& elem = *(first + i);
// do whatever you want with elem
}
}
Количество потоков может быть установлена во время выполнения с помощью переменной в OMP_NUM_THREADS
среды.
Допустим, у меня есть не так дорогостоящая операция в цикле, можно ли разбить петлю пополам? На нитке одна половина другого остальное? То же самое с 3 и так далее потоками? – Exagon
Что вы итерируете? Можете ли вы использовать индексы для циклирования? –
@Exagon От вас зависит, что вы принимаете работу из потоков. Вы можете создавать условия в циклах, с помощью которых вы можете разделить работу. –
Это можно сделать с помощью threads
, а именно pthreads
библиотечной функции, которая может использоваться для одновременного выполнения операций.
Вы можете прочитать о них здесь: http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm
станд :: нить также может быть использован: http://www.cplusplus.com/reference/thread/thread/
Ниже приведен код, в котором я использовать идентификатор потока для каждого потока, чтобы разбить массив на две половинки:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 2
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
void *splitLoop(void *threadid)
{
long tid;
tid = (long)threadid;
//cout << "Hello World! Thread ID, " << tid << endl;
int start = (tid * 5);
int end = start + 5;
for(int i = start;i < end;i++){
cout << arr[i] << " ";
}
cout << endl;
pthread_exit(NULL);
}
int main()
{
pthread_t threads[NUM_THREADS];
int rc;
int i;
for(i=0; i < NUM_THREADS; i++){
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL,
splitLoop, (void *)i);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
Также помните, при компиляции вы должны использовать -lpthread
флаг.
Ссылка на решение на Ideone: http://ideone.com/KcsW4P
Да, что может быть достигнуто, вы можете указать «начальный индекс» и «конец индекса» в функции, которую вы используете, и соответствующим образом изменить ее для каждого используемого потока. – uSeemSurprised
Функция 'pthread_create' принимает в стороне аргумент, который содержит имя функции, которую вы хотите использовать ваши потоки, вы можете изменить эти аргументы функций для достижения желаемого результата. – uSeemSurprised
Почему он хочет использовать pthreads, когда у него есть 'std :: thread'? –
std::async
может пригодиться здесь, если вы с удовольствием разрешите параллелизм C++
.
Пример из cppreference.com:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
template <typename RAIter>
int parallel_sum(RAIter beg, RAIter end)
{
auto len = end - beg;
if(len < 1000)
return std::accumulate(beg, end, 0);
RAIter mid = beg + len/2;
auto handle = std::async(std::launch::async,
parallel_sum<RAIter>, mid, end);
int sum = parallel_sum(beg, mid);
return sum + handle.get();
}
int main()
{
std::vector<int> v(10000, 1);
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
}
wow thanks Я думаю, что буду использовать это – Exagon
Есть ли какая-либо документация о том, как C++ обрабатывает параллельные задачи и асинхронные? – Exagon
Первый параметр 'std :: async()' указывает, какую свободу вы предоставляете структуре (в первую очередь, разрешаете ли вы использовать поток переднего плана). Что касается того, что он делает для фона - он специфичен для компилятора, но, скорее всего, на большинстве компиляторов будет один пул потоков с N = количеством ядер процессора на коробке. Лучшая документация по использованию, к которой я пришел, до сих пор является частью параллелизма из последней книги Майера. – bobah
С параллельных алгоритмов в C++ 17 теперь мы можем использовать:
std::vector<std::string> foo;
std::for_each(
std::execution::par_unseq,
foo.begin(),
foo.end(),
[](auto&& item)
{
//do stuff with item
});
вычислить петли параллельно. Первый параметр указывает execution policy
С C++ 11 вы можете распараллелить цикл for только несколькими строками кодов. Это раскалывает для цикла на более мелкие куски и присвоить каждому суб цикл в тему:
/// Basically replacing:
void sequential_for(){
for(int i = 0; i < nb_elements; ++i)
computation(i);
}
/// By:
void threaded_for(){
parallel_for(nb_elements, [&](int start, int end){
for(int i = start; i < end; ++i)
computation(i);
});
}
Или жгуты класса:
struct My_obj {
/// Replacing:
void sequential_for(){
for(int i = 0; i < nb_elements; ++i)
computation(i);
}
/// By:
void threaded_for(){
parallel_for(nb_elements, [this](int s, int e){ this->process_chunk(s, e); });
}
void process_chunk(int start, int end)
{
for(int i = start; i < end; ++i)
computation(i);
}
};
Чтобы сделать это, вам нужно всего лишь поместить код ниже файл заголовка и использовать его по желанию:
#include <algorithm>
#include <thread>
#include <functional>
#include <vector>
/// @param[in] nb_elements : size of your for loop
/// @param[in] functor(start, end) :
/// your function processing a sub chunk of the for loop.
/// "start" is the first index to process (included) until the index "end"
/// (excluded)
/// @code
/// for(int i = start; i < end; ++i)
/// computation(i);
/// @endcode
/// @param use_threads : enable/disable threads.
///
///
static
void parallel_for(unsigned nb_elements,
std::function<void (int start, int end)> functor,
bool use_threads = true)
{
// -------
unsigned nb_threads_hint = std::thread::hardware_concurrency();
unsigned nb_threads = nb_threads_hint == 0 ? 8 : (nb_threads_hint);
unsigned batch_size = nb_elements/nb_threads;
unsigned batch_remainder = nb_elements % nb_threads;
std::vector<std::thread> my_threads(nb_threads);
if(use_threads)
{
// Multithread execution
for(unsigned i = 0; i < nb_threads; ++i)
{
int start = i * batch_size;
my_threads[i] = std::thread(functor, start, start+batch_size);
}
}
else
{
// Single thread execution (for easy debugging)
for(unsigned i = 0; i < nb_threads; ++i){
int start = i * batch_size;
functor(start, start+batch_size);
}
}
// Deform the elements left
int start = nb_threads * batch_size;
functor(start, start+batch_remainder);
// Wait for the other thread to finish their task
if(use_threads)
std::for_each(my_threads.begin(), my_threads.end(), std::mem_fn(&std::thread::join));
}
- 1. C++ параллельные петли
- 2. параллельные (несимметричные) петли в python
- 3. Параллельные - потоки? петли?
- 4. Параллельные goroutines внутри петли for
- 5. предотвратить параллельные петли под управлением
- 6. Параллельные петли с пакетом dataframe в Julia
- 7. параллельные петли foreach производят ошибку mclapply
- 8. Как использовать две параллельные петли, Python?
- 9. Возможно ли параллельные петли «поперечного коллапса»?
- 10. Параллельные петли для определения размера папки
- 11. Параллельные петли и случайные производят нечетные результаты
- 12. Как вложить параллельные петли в последовательный цикл с помощью OpenMP
- 13. Параллельные коллекции в C#
- 14. рисования Параллельные линии в C#
- 15. C Параллельные процессы
- 16. C++ Параллельные запросы GET
- 17. Параллельные параллельные двоичные считыватели
- 18. Бесконечные петли в C++
- 19. Непонимание петли в C++?
- 20. C++ Вложенные в петли
- 21. Бесконечные петли в C
- 22. Многопроцессорные параллельные петли не могут быть вложены под потоками
- 23. Параллельные параллельные тесты
- 24. Параллельные параллельные сеточные сетки
- 25. WebDriver: параллельные параллельные тесты
- 26. C Параллельные процессы и трубы
- 27. Петли в C# c C++ и java
- 28. Просьба посоветуйте для петли петли C++
- 29. параллельные вычисления в C и mathematica
- 30. Параллельные функции возвращают различные результаты в C#
Использование потоков - хороший вариант. –
Не правда ли, дорого ли инициализировать потоки? – Exagon
По сравнению с вызовом fork(). Нитки не дорогие, поскольку они делят ресурсы из основного потока, за исключением того, что у них есть собственный компьютер, регистры и стек. –