чел, как правильно его использовать? - PullRequest
1 голос
/ 14 февраля 2012

Следующий код:

#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

Я должен использовать «комбинируемый», я думаю, но документация янашел об этом не очень хорошо.Знаете ли вы, как заставить этот код работать правильно?Что если vett - это двумерный вектор?

Поскольку я хотел бы изучать параллельные вычисления, стоит ли изучать эту новую библиотеку Microsoft или есть лучшие альтернативы?

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

Основная проблема с вашим кодом - это индексная переменная 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 после завершения цикла.

1 голос
/ 14 февраля 2012

Хорошее практическое правило для параллельного кода - минимизировать количество общих переменных.

Как следствие, вы никогда не должны использовать [&] в качестве лямбда-захвата для parallel_for (или std::thread).Захватывайте только те переменные, которые должны быть общими.

Если бы вы сделали это, вы бы обнаружили проблему, указанную @Blastfurnace, а именно, что i было общим для всех работников.

...