博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TBB之Exceptions and Cancellation
阅读量:4058 次
发布时间:2019-05-25

本文共 2818 字,大约阅读时间需要 9 分钟。

Intel TBB支持exceptions和cacellation。当Intel TBB算法里的代码抛出exception时,会发生下面的事情:

  • exception被捕获,在算法里更远的exceptions被忽略。
  • 算法被取消,未实现的迭代不被执行,如果内部嵌套Intel TBB的并行程序,它会被取消。
  • 一旦算法所有部分停止,那么调用这个算法的线程会抛出一个exception。
#include "tbb/tbb.h"#include 
#include
using namespace tbb;using namespace std;vector
Data;struct Update { void operator()( const blocked_range
& r ) const { for( int i=r.begin(); i!=r.end(); ++i ) Data.at(i) += 1; }};int main() { Data.resize(1000); try { parallel_for( blocked_range
(0, 2000), Update()); } catch( captured_exception& ex ) { cout << "captured_exception: " << ex.what() << endl; } catch( out_of_range& ex ) { cout << "out_of_range: " << ex.what() << endl; } return 0;}

parallel_for尝试迭代vector的2000个元素,但是里面只有1000个元素,因此在执行这个算法期间,表达式Data.at(i)抛出一个std::out_of_range,当exception发生时,算法取消并且在调用parallel_for时抛出一个exception。

Cancellation Without An Exception

为了取消算法,但是不抛出异常,使用表达式task::self().cancel_group_execution()。task::self参考Intel TBB task,调用cancel_group_execution()取消task_group_context里所有的任务,下一部将详细解释,如果它确实引起cancellation,那么方法返回true,如果task_group_context已经取消了,它返回false。

下面的例子展示怎样使用task::self().cancel_group_execution():

#include "tbb/tbb.h"#include 
#include
using namespace tbb;using namespace std;vector
Data;struct Update { void operator()( const blocked_range
& r ) const { for( int i=r.begin(); i!=r.end(); ++i ) if( i
(0, 2000), Update()); return 0;}

Cancellation and Nested Parallelism

目前讨论的都是假设没有内部嵌套parallelism的情况,跳过task_group_context的细节,这部分介绍这2点。

Intel TBB算法通过创建一系列的task对象来执行的,默认情况下,这些task和task_group_context关联,且task_group_context由算法创建,取消一个task_group_context相当于取消所有子task_group_context对象。

exceptions向前传播,cancellation向后传播。例如,考虑下图的树状图,设想每个节点表示一个算法和一个task_group_context。

这里写图片描述

假设C节点上的算法抛出exception并且没有节点捕获这个exception,Intel TBB向前传播exception,向下取消相关子树的exception,如下:

这里写图片描述
这里写图片描述

如果你的代码在任何级别上捕获这个exception,那么Intel TBB不会向更远的方向传播。例如,一个exception不会逃离出一个parallel_for,那么parallel_for不会引起其他迭代的cancellation。

为了阻止向下传播cancellation,在stack上构造一个”isolated”task_group_context,并且显示的传递给这个算法,如下:

#include "tbb/tbb.h"bool Data[1000][1000];int main() {    try {        parallel_for( 0, 1000, 1,            []( int i ) {                task_group_context root(task_group_context::isolated);                parallel_for( 0, 1000, 1,                    []( int j ) {                    Data[i][j] = true;                },                root);            throw "oops";        });    } catch(...) {    }    return 0;}

这个例子执行2个parallel循环,外部的循环在i上进行,内部的循环在j上进行,isolated的task_group_context root创建保护内部循环免受cacellation的干扰,当exception传播到外部循环,任何未使用的迭代会取消,但是内部循环不会取消,因此当程序结束时,Data每一行可能是不同的,但是在同一行里,元素会是全部的false或者true,而不是一个混合。

你可能感兴趣的文章
Truncate 表之恢复
查看>>
Oracle DG failover 后恢复
查看>>
mysql 主从同步配置
查看>>
为什么很多程序员都选择跳槽?
查看>>
mongdb介绍
查看>>
mongdb在java中的应用
查看>>
区块链技术让Yotta企业云盘为行政事业服务助力
查看>>
Yotta企业云盘更好的为媒体广告业服务
查看>>
Yotta企业云盘助力科技行业创高峰
查看>>
Yotta企业云盘更好地为教育行业服务
查看>>
Yotta企业云盘怎么帮助到能源化工行业
查看>>
企业云盘如何助力商业新发展
查看>>
医疗行业运用企业云盘可以带来什么样的提升
查看>>
媒体广告业如何将内容资产进行高效地综合管理与利用
查看>>
能源化工要怎么管控核心数据
查看>>
媒体广告业如何运用云盘提升效率
查看>>
企业如何运用企业云盘进行数字化转型-实现新发展
查看>>
司法如何运用电子智能化加快现代化建设
查看>>
iSecret&nbsp;1.1&nbsp;正在审核中
查看>>
IOS开发的开源库
查看>>