【问题标题】:Understanding concurrency of tbb::parallel_reduce理解 tbb::parallel_reduce 的并发性
【发布时间】:2017-03-23 10:33:36
【问题描述】:

我将tbb::parallel_reduce(range,body) 的命令式形式用作documented here。医生说:

parallel_reduce 使用拆分构造函数为每个线程制作一个或多个主体副本。它可以在主体的 operator() 或方法连接同时运行时复制主体。您有责任确保此类并发的安全性。

所以我知道Body::Body( Body&, split ) 可以像Body::operator()Body::join( Body& rhs ) 那样运行。

我的问题是

1) Body::operator()Body::join( Body& rhs ) 可以同时运行吗?

2) Body::join( Body& rhs )可以安全修改rhs吗?

W.r.t. 1),我相信join只能在operator()完成后调用。此外,查看英特尔文档中的示例,很明显他们可以修改相同的数据而不会出现数据竞争问题:

struct Sum {
    float value;
    ...
    void operator()( const blocked_range<float*>& r ) {
        value = ...;
    }
    void join( Sum& rhs ) {value += rhs.value;}
};               

【问题讨论】:

    标签: c++ concurrency tbb


    【解决方案1】:

    tbb::parallel_reduce 使用的Body 对象的生命周期为:

    1. 它由拆分构造函数创建为另一个 Body 对象的“右侧”,而该对象又被更新为仅处理“左侧”。
    2. operator() 应用于一个或多个结果范围。
    3. 它可以用作拆分新主体的构造函数的参数(是的,不止一次),并按照上面的 #1 进行更新。
    4. 它的方法join() 在#3 中为从它拆分出来的每个对象调用。
    5. 它以rhs 的形式连接到它被拆分的主体对象。
    6. 加入后销毁。

    上述操作中,#3可以同时运行到#2和#4;其余的都是顺序的,即使不一定由单个线程调用。换句话说,当一个主体为某些子范围累积部分归约或连接另一个主体的结果时,可以通过拆分新主体的构造函数来更新它。这是可能需要保护的地方,但通常这些调用会访问身体的不同部位。

    所以,你的问题的答案是:

    1) Body::operator()Body::join( Body&amp; rhs ) 可以同时运行吗?

    没有。 join() 仅在对 operator() 的所有调用之后调用,thisrhs 均如此。

    2) Body::join( Body&amp; rhs )可以安全地修改rhs吗?

    是的,可以。但除了可能在加入期间移动其内容并相应地更新状态之外,修改rhs 几乎没有意义,因为它将在join() 调用之后立即被销毁。

    【讨论】:

      【解决方案2】:

      关于方法的并发调用中涉及哪些实例的文档不够清楚。但它暗示:

      在典型使用中,安全性不需要额外的努力。

      同一个实例没有并发。因此,可以安全地拆分或连接两个实例,就像在串行代码中一样。 operator() 也不能在同一个实例上同时调用。所以文档必须真正说:

      它可能会复制一个主体,而主体的 operator() 或方法连接同时在不同的实例上运行

      顺便说一句,报价

      parallel_reduce 递归地将范围拆分为子范围,以使每个子范围的 is_divisible() 为 false。`

      仅对simple_partitioner为真,对于其他分区器,它可以在到达is_divisible() == false之前停止分裂

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多