concurrent_vector не работает внутри parallel_for (PPL)

ниже приведен пример рабочего кода (parallel_for с использованием Parallel Pattern Library (ppl)). Основная проблема здесь заключается в SQR < concurrent_vector> сохраненные значения меняются при каждом выполнении, но это не должно быть!

я использовал < concurrent_vector> для произвольного доступа, почему он не работает?

#include <iostream>
#include <ppl.h>
#include <concurrent_vector.h>

using namespace std;
using namespace concurrency;

const int a = 10, b = 30;

critical_section cs;

int main() {

concurrent_vector< int > labels( a * b );

concurrent_vector< int > sqr( 5 );

// filling label vector
for ( int y = 0; y < b; y++ ) {
for ( int x = 0; x < a; x++ ) {

if( x<2 && y>3 )
labels[ a * y + x ] = 1;
else if( x<30 && y<5 )
labels[ a * y + x ] = 2;
else if( x>5 && y>10 )
labels[ a * y + x ] = 3;
else if( x>2 && y>20 )
labels[ a * y + x ] = 4;
}
}

// printing
for ( int y = 0; y < b; y++ ) {
for ( int x = 0; x < a; x++ ) {

cout << labels[ a * y + x ] << ", ";
}
cout << endl;
}

parallel_for ( 0, b, [ & ]( int y ) {
for ( int x = 0; x < a; x++ ) {

//cs.lock();  // when i used it's working but slow
int i = labels[ a * y + x ];
//cs.unlock();

if ( i < 0 ) continue;

sqr[ i ] ++;
}
} );

for( int i=0; i<5; i++ )
cout << sqr[i] << ", ";
cout << "" << endl;

system ("pause");

return 0;
}

0

Решение

С помощью task_group::wait Метод должен быть быстрее (так как вам не нужно каждый раз блокировать / разблокировать), и он может работать так, как вы ожидаете.

Этот метод блокирует текущую задачу, пока задачи другой задачи
группа завершила свою работу.

Смотрите MSDN: Параллельные задачи.

Обновить: Я провел несколько временных тестов и, похоже, это не решение (кроме того, что оба не справляются с большими входами данных на моем двухъядерном процессоре).
Это может быть ошибкой «дизайна» в concurrent_vector, как в Intel TBB — tbb :: concurrent_vector возвращает неправильный размер

-1

Другие решения

Вы не используете какие-либо функции параллельного вектора, которые имеют отношение к параллелизму. Фактически, вы можете заменить его стандартным вектором без разницы … Очевидно, значения i перекрываются при каждом выполнении ядра. Нет абсолютно никакой гарантии, что одновременные записи в один и тот же элемент вектора синхронизированы. Таким образом, вы получаете случайные результаты — это просто следствие скачек данных при неатомарных записях.

2

По вопросам рекламы [email protected]