Чел, как правильно его использовать?
Следующий код:
#include <ppl.h>
int i;
vector<int> val(10),summ(10,0);
for(i=0;i<10;i++) val[i]=i;
parallel_for(0, 10, [&] (int y){
vector<int> vett(1000);
double vall=val[y];
for(i=0;i<vett.size();i++)
vett[i]=vall;
for(i=0;i<vett.size();i++)
summ[y]+=vett[i];
});
for(i=0;i<10;i++)
cout<<summ[i]<<endl;
Производит случайный вывод как: 0 1000 1468 204 3600 25 5898 7000 7456 1395
Я должен использовать "combinable", но документация, которую я нашел, не очень хороша. Знаете ли вы, как заставить этот код работать правильно? Что если ветт является 2d вектором?
Поскольку я хотел бы изучать параллельные вычисления, стоит ли изучать эту новую библиотеку Microsoft или есть лучшие альтернативы?
2 ответа
Основная проблема с вашим кодом i
подстрочная переменная. Он используется несколькими параллельными задачами одновременно. За этим следует хаос, и это является причиной неудачных результатов. Самое простое решение - объявить циклы в вашей лямбде следующим образом:
for(int i=0;i<vett.size();i++)
vett[i]=vall;
for(int i=0;i<vett.size();i++)
summ[y]+=vett[i];
Обратите внимание, что каждый индекс цикла объявлен в for
инициализация цикла. Это более идиоматическое использование и может использоваться во всех ваших циклах, если вам действительно не нужно конечное значение i
после окончания цикла.
Хорошее практическое правило для параллельного кода - минимизировать количество общих переменных.
Как следствие, вы никогда не должны использовать [&]
как лямбда-захват для parallel_for
(или же std::thread
). Захват только те переменные, которые должны быть разделены.
Если бы вы сделали это, вы бы обнаружили проблему, указанную @Blastfurnace, а именно: i
был разделен между всеми работниками.