Параллельный цикл С++ без блокировки критической секции с использованием PPL

в приведенном ниже коде есть цикл parallel_for, реализованный с помощью PPL. Основная проблема здесь; Значения вектора abc неверны, когда я был прокомментирован cs.lock() и cs.unlock(). Я использую тип concurrency_vector для произвольного доступа к значениям массива, но, похоже, он не работает. Блокировка критического раздела, он работает, но медленно. Кроме того, для ускорения я использовал индексацию для хранения значений, а не 2D-concurrency_vector. В чем проблема, без блокировки критической секции, что я пропустил?

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

using namespace concurrency;
using namespace std;

int test_function()
{
    critical_section cs;

    concurrent_vector< double > abc( 300 * 400, 1000 );

    parallel_for ( 0, 1000, [ & ]( int k ) {
        for ( int y = 0; y < 300; y++ ) {
            for ( int x = 0; x < 400; x++ ) {

                /// k is using with some calculations for thr

                cs.lock();

                if ( thr < abc[ 400 * y + x ] ) {

                    abc[ 400 * y + x ] = thr;
                }

                cs.unlock();
            }
        }
    } );
}

person user2055437    schedule 16.02.2013    source источник


Ответы (1)


Почему вы ожидаете, что это сработает? Если это выполняется параллельно без блокировки, abc[400*y+x] может и будет изменяться между оператором if и присваиванием, тем самым нарушая вашу логику. Сам векторный тип, являющийся потокобезопасным, не имеет к этому никакого отношения.

person Cubic    schedule 16.02.2013
comment
спасибо за быстрый ответ, я прав, if-statement вызывает проблему, и мы должны ее защитить? - person user2055437; 16.02.2013
comment
@user2055437 user2055437 Кажется, это так, если только в ваших расчетах нет других вещей, которые могут его нарушить. И, конечно, это будет медленно - блокировка/разблокировка медленная, и вам нужно сделать это очень много. Вы также в конечном итоге с большим количеством ненужного ожидания. Вы можете увидеть некоторое улучшение производительности, если вместо этого будете использовать детальные блокировки (создайте 300*400 критических секций, по одной для каждого элемента abc, а затем используйте их для блокировки). - person Cubic; 16.02.2013
comment
извините, что украл ваше время, можете ли вы привести пример блока кода или примеры сайтов, книгу, которую я могу прочитать напоследок, вы говорите, побыстрее? - person user2055437; 16.02.2013
comment
@user2055437 user2055437 Это может ускорить его (на самом деле, вероятно, так и будет). Я хотел бы сделать это в чате, к сожалению, вам нужно 20 представителей, чтобы говорить там. В основном вместо critical_section cs; critical_section css[300*400] и вместо cs.lock()/cs.unlock() cs[400*y+x].lock()/cs[400*y+x].unlock(). Я не уверен, насколько дорого создание и хранение критических секций, поэтому я не уверен, поможет ли это, но если они настолько недороги, как я думаю, то это должно улучшить ситуацию. - person Cubic; 16.02.2013