【问题标题】:concurrent_vector is not working inside parallel_for ( PPL )concurrent_vector 在 parallel_for ( PPL ) 中不起作用
【发布时间】:2013-02-23 13:26:14
【问题描述】:

下面有一个示例工作代码(parallel_for 使用并行模式库( ppl ))。这里的主要问题是 sqr 存储的值在每次执行中都会发生变化,但它不应该是!

我使用 进行随机访问,为什么它不起作用?

#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;
}

【问题讨论】:

  • "parallel_for 方法不保证任何特定的执行顺序。与顺序循环不同,一些较高值的索引可能在一些较低值的索引之前处理。" (msdn.microsoft.com/en-us/library/gg663527.aspx#sec2)。
  • ok,但是所有线程执行结束,结果必须相同。标签的计数( 1, 2, 3 )没有改变。在代码获得正确结果之前我错过了什么或应该做些什么?
  • 我猜,如果使用锁解决了问题,那么你的假设是错误的。
  • 你是正确的锁定正在工作,但它会杀死更大数组大小的并行性。所以,我正在寻找其他解决方案或观点

标签: c++ concurrency parallel-processing ppl parallel-for


【解决方案1】:

您没有使用任何与并发相关的并发向量功能。事实上,你可以用标准向量替换它,没有区别……显然, i 的值在内核的每次执行中重叠。绝对不能保证对向量的同一元素的并发写入是同步的。因此,您会得到随机结果 - 这只是非原子写入数据竞争的结果。

【讨论】:

    【解决方案2】:

    使用task_group::wait 方法应该更快(因为您不必每次都锁定/解锁)并且它可能会按您的预期工作。

    此方法阻塞当前任务,直到另一个任务的任务 小组已经完成了他们的工作。

    参见 MSDN:Parallel Tasks

    更新:我已经运行了一些计时测试,似乎这不是一个解决方案(除了我的双核上的大数据输入都失败了)。 这可能是 Intel 的 TBB 中“concurrent_vector 中的设计”的错误 - tbb::concurrent_vector returns wrong size

    【讨论】:

      猜你喜欢
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      • 2011-08-23
      • 1970-01-01
      相关资源
      最近更新 更多