- 浏览: 242862 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
saiyaren:
你对hiphop的深入程度到了什么程度了?想和你进行探讨一下
facebook hiphop php vm 实现概述 -
eric_weitm:
lj3362569 写道可以再讲具体点么?还有现有的hipho ...
facebook hiphop php vm 实现概述 -
lj3362569:
可以再讲具体点么?还有现有的hiphop不支持哪些功能?
facebook hiphop php vm 实现概述
TBB(Intel Threading Building Blocks)学习笔记
并行与并发是相对的,OS里讲的是并发而在架构方面更多的是说并行。并行是分多个层面的,个人认为基本上可以分为这么几个层面:1、指令级的并行;即所谓的微程序、指令流水线等,现在cpu的一级缓存、二级缓存都很大,所以这个cache的效果还是比较好的(基于局部性原理)2、线程级的并行;即同一个时刻多个函数在运行(现在的cpu好像都是多核的)3、服务级别的(比如一个游戏服务器中有商店服务、也有战斗服务、聊天服务等 这里的每个服务可能对应多个逻辑线程)4、节点级别的;即所谓的分布式系统,多个节点互相配合,使整个系统在逻辑上成为一个单一的系统。(google、qq等这些海量访问的服务统统是分布式的)一般来说,第一个级别的并行直接做在硬件里面,第二个级别的并行会有一些基础的框架,第三和第四个级别的并行就是应用程序自己的架构的问题了。这里面实际上有一个争论:是在算法并行化上面花心思去研究还是采用分布式的框架来面对问题规模的增长?实际上2者各有利弊,前者可以充分利用已有硬件,但是对程序员的要求较高,维护开发成本高,风险大;后者容易实现但是浪费硬件,在有些情况下不是所有问题都可以用加个机器的方式可以解决的(比如客户端上的多媒体软件,其计算量极大,总不能要求所有用户都升级吧。)
Intel Threading Building Blocks,是为了方便程序员使用多核处理器的C++库,应该是对应上面提到的第二个级别的并行的。
一、TBB应该提供哪些东西?
用TBB就是为了程序的并行化,那么程序员需要什么样的支持呢?最理想的情况是已有的代码不作任何修改,换一个编译器重新编译一下就OK,现在看来这个还不太现实。要有更好的效率就需要有更多的启发式信息,同时也就要求程序员要了解很多细节。整个程序逻辑没办法自动并行化,那就针对控制流进行并行化吧,所以TBB中提供了 parallel_for、parallel_while、 parallel_reduce等;(这些是TBB给C++程序员的比较高层的接口)并行肯定是多线程,这样的话数据竞争问题就比较棘手,所以TBB提供并发容器;如果觉得
TBB提供的这些接口还没有办法解决性能问题,那就可以更深入的研究使用mutex、atomic、task等了;可以看出,TBB从几个层次上为程序员提供了支持。
二、TBB提供的接口
由底层到高层,task_scheduler--------concurrent_container--------parallel_for---pipeline
简单说,TBB帮我们调度一个个task(比OS的调度要高效),实现高效的并行算法
三、细节
1、parallel_for 适用场合:多个数据或请求彼此没有依赖关系,所要进行的操作是一样的(典型SPMD)
例子:
// 典型的c++泛型编程 blocked_range 是要处理的多个数据,3个参数依次是开始的指针(迭代器)、结束指针、每个任务分配的数据数
// parallel_forFibBody可以简单理解为一个函数对象(c++里是用运算符重载实现的,即()是通信的接口)
parallel_for( blocked_range<int>( 1, my_n, 10 ), parallel_forFibBody(my_stream) );
struct parallel_forFibBody {
QueueStream &my_stream;
//! fill functor arguments
parallel_forFibBody(QueueStream &s) : my_stream(s) { }
// 这里是并行的代码
void operator()( const blocked_range<int> &range ) const {
int i_end = range.end();
for( int i = range.begin(); i != i_end; ++i ) {
my_stream.Queue.push( Matrix1110 ); // push initial matrix
}
}
};
2、parallel_reduce 适合于需要汇总的情况,即各个数据的结果需要汇总回来
例子:(注意分发下去和汇总回来的方法)
float ParallelSumFoo( const float a[], size_t n ) {
SumFoo sf(a);
parallel_reduce(blocked_range<size_t>(0,n,IdealGrainSize), sf );
return sf.sum;
}
class SumFoo {
float* my_a;
public:
float sum;
void operator()( const blocked_range<size_t>& r ) {
float *a = my_a;
for( size_t i=r.begin(); i!=r.end(); ++i )
sum += Foo(a[i]);
}
SumFoo( SumFoo& x, split ) : my_a(x.my_a), sum(0) {} // 分发任务,注意这个构造器要求是线程安全的
void join( const SumFoo& y ) {sum+=y.sum;} // 收集汇总结果
SumFoo(float a[] ) :
my_a(a), sum(0)
{}
};
3、parallel_while 有时不知道循环何时结束,即使用for的end未知,在这种情况下可以使用parallel_while
例子:注意pop_if_present、typedef Item* argument_type、operator()等部分的处理
// 串行版本
void SerialApplyFooToList( Item*root ) {
for( Item* ptr=root; ptr!=NULL; ptr=ptr->next )
Foo(pointer->data);
}
// 并行版本
class ItemStream {
Item* my_ptr;
public:
bool pop_if_present( Item*& item ) { // 用于提供下一个迭代器
if( my_ptr ) {
item = my_ptr;
my_ptr = my_ptr->next;
return true;
} else {
return false;
}
};
ItemStream( Item* root ) : my_ptr(root) {}
}
class ApplyFoo {
public:
void operator()( Item* item ) const { // 要求一定是const的
Foo(item->data);
}
typedef Item* argument_type; // 此句是必须的
};
void ParallelApplyFooToList( Item*root ) {
// parallel_while是个class
parallel_while<ApplyFoo> w; // 先建立个对象
ItemStream stream;
ApplyFoo body;
// 第一个参数提供数据指针,第二个参数提供函数体
w.run( stream, body );
}
四、并发容器
大部分程序都有容器类,在多线程环境下就有数据污染的问题,为了使并发的线程串行化,一般是使用加锁的办法,如果这个
容器由程序员自己来实现,难度还是比较大的,这样就需要有线程安全的容器类。
1、concurrent_hash_map
hash接口与stl类似
2、concurrent_vector
grow_by(n) 插入n个item(动态增长)
grow_to_at_least()设定容器的大小
size() 包括正在并发增长的部分 因为有可能会同时取,所以程序员需要自己维护自己的class的线程安全性
clear() 不是线程安全的
3、concurrent_queue
pop_if_present(item) 非阻塞,
pop() 阻塞,
concurrent_queue::size() 负数时表示有多少个消费者在等待
set_capacity()指定队列大小,会使push操作被阻塞
在并行时,paralell_while pipeline 的效率要高于concurrent_queue
五、如果觉得TBB的加锁效率不高,可以自己控制锁
最常用的是spin lock
六、整个TBB引擎的核心是 Task Scheduler(基于任务图来实现)
提高效率的核心是threading stealing,保证cpu的效率
七、小结
要使用TBB进行并行化,首先程序员要知道哪些是可以并行化;其次,要熟悉TBB并行化的框架(主要是泛型编程);再次,程序员要大概知道
并行算法的执行步骤;最后,利用TBB的组件,实现并行化的算法。总体上来说,还是不太好用的
并行与并发是相对的,OS里讲的是并发而在架构方面更多的是说并行。并行是分多个层面的,个人认为基本上可以分为这么几个层面:1、指令级的并行;即所谓的微程序、指令流水线等,现在cpu的一级缓存、二级缓存都很大,所以这个cache的效果还是比较好的(基于局部性原理)2、线程级的并行;即同一个时刻多个函数在运行(现在的cpu好像都是多核的)3、服务级别的(比如一个游戏服务器中有商店服务、也有战斗服务、聊天服务等 这里的每个服务可能对应多个逻辑线程)4、节点级别的;即所谓的分布式系统,多个节点互相配合,使整个系统在逻辑上成为一个单一的系统。(google、qq等这些海量访问的服务统统是分布式的)一般来说,第一个级别的并行直接做在硬件里面,第二个级别的并行会有一些基础的框架,第三和第四个级别的并行就是应用程序自己的架构的问题了。这里面实际上有一个争论:是在算法并行化上面花心思去研究还是采用分布式的框架来面对问题规模的增长?实际上2者各有利弊,前者可以充分利用已有硬件,但是对程序员的要求较高,维护开发成本高,风险大;后者容易实现但是浪费硬件,在有些情况下不是所有问题都可以用加个机器的方式可以解决的(比如客户端上的多媒体软件,其计算量极大,总不能要求所有用户都升级吧。)
Intel Threading Building Blocks,是为了方便程序员使用多核处理器的C++库,应该是对应上面提到的第二个级别的并行的。
一、TBB应该提供哪些东西?
用TBB就是为了程序的并行化,那么程序员需要什么样的支持呢?最理想的情况是已有的代码不作任何修改,换一个编译器重新编译一下就OK,现在看来这个还不太现实。要有更好的效率就需要有更多的启发式信息,同时也就要求程序员要了解很多细节。整个程序逻辑没办法自动并行化,那就针对控制流进行并行化吧,所以TBB中提供了 parallel_for、parallel_while、 parallel_reduce等;(这些是TBB给C++程序员的比较高层的接口)并行肯定是多线程,这样的话数据竞争问题就比较棘手,所以TBB提供并发容器;如果觉得
TBB提供的这些接口还没有办法解决性能问题,那就可以更深入的研究使用mutex、atomic、task等了;可以看出,TBB从几个层次上为程序员提供了支持。
二、TBB提供的接口
由底层到高层,task_scheduler--------concurrent_container--------parallel_for---pipeline
简单说,TBB帮我们调度一个个task(比OS的调度要高效),实现高效的并行算法
三、细节
1、parallel_for 适用场合:多个数据或请求彼此没有依赖关系,所要进行的操作是一样的(典型SPMD)
例子:
// 典型的c++泛型编程 blocked_range 是要处理的多个数据,3个参数依次是开始的指针(迭代器)、结束指针、每个任务分配的数据数
// parallel_forFibBody可以简单理解为一个函数对象(c++里是用运算符重载实现的,即()是通信的接口)
parallel_for( blocked_range<int>( 1, my_n, 10 ), parallel_forFibBody(my_stream) );
struct parallel_forFibBody {
QueueStream &my_stream;
//! fill functor arguments
parallel_forFibBody(QueueStream &s) : my_stream(s) { }
// 这里是并行的代码
void operator()( const blocked_range<int> &range ) const {
int i_end = range.end();
for( int i = range.begin(); i != i_end; ++i ) {
my_stream.Queue.push( Matrix1110 ); // push initial matrix
}
}
};
2、parallel_reduce 适合于需要汇总的情况,即各个数据的结果需要汇总回来
例子:(注意分发下去和汇总回来的方法)
float ParallelSumFoo( const float a[], size_t n ) {
SumFoo sf(a);
parallel_reduce(blocked_range<size_t>(0,n,IdealGrainSize), sf );
return sf.sum;
}
class SumFoo {
float* my_a;
public:
float sum;
void operator()( const blocked_range<size_t>& r ) {
float *a = my_a;
for( size_t i=r.begin(); i!=r.end(); ++i )
sum += Foo(a[i]);
}
SumFoo( SumFoo& x, split ) : my_a(x.my_a), sum(0) {} // 分发任务,注意这个构造器要求是线程安全的
void join( const SumFoo& y ) {sum+=y.sum;} // 收集汇总结果
SumFoo(float a[] ) :
my_a(a), sum(0)
{}
};
3、parallel_while 有时不知道循环何时结束,即使用for的end未知,在这种情况下可以使用parallel_while
例子:注意pop_if_present、typedef Item* argument_type、operator()等部分的处理
// 串行版本
void SerialApplyFooToList( Item*root ) {
for( Item* ptr=root; ptr!=NULL; ptr=ptr->next )
Foo(pointer->data);
}
// 并行版本
class ItemStream {
Item* my_ptr;
public:
bool pop_if_present( Item*& item ) { // 用于提供下一个迭代器
if( my_ptr ) {
item = my_ptr;
my_ptr = my_ptr->next;
return true;
} else {
return false;
}
};
ItemStream( Item* root ) : my_ptr(root) {}
}
class ApplyFoo {
public:
void operator()( Item* item ) const { // 要求一定是const的
Foo(item->data);
}
typedef Item* argument_type; // 此句是必须的
};
void ParallelApplyFooToList( Item*root ) {
// parallel_while是个class
parallel_while<ApplyFoo> w; // 先建立个对象
ItemStream stream;
ApplyFoo body;
// 第一个参数提供数据指针,第二个参数提供函数体
w.run( stream, body );
}
四、并发容器
大部分程序都有容器类,在多线程环境下就有数据污染的问题,为了使并发的线程串行化,一般是使用加锁的办法,如果这个
容器由程序员自己来实现,难度还是比较大的,这样就需要有线程安全的容器类。
1、concurrent_hash_map
hash接口与stl类似
2、concurrent_vector
grow_by(n) 插入n个item(动态增长)
grow_to_at_least()设定容器的大小
size() 包括正在并发增长的部分 因为有可能会同时取,所以程序员需要自己维护自己的class的线程安全性
clear() 不是线程安全的
3、concurrent_queue
pop_if_present(item) 非阻塞,
pop() 阻塞,
concurrent_queue::size() 负数时表示有多少个消费者在等待
set_capacity()指定队列大小,会使push操作被阻塞
在并行时,paralell_while pipeline 的效率要高于concurrent_queue
五、如果觉得TBB的加锁效率不高,可以自己控制锁
最常用的是spin lock
六、整个TBB引擎的核心是 Task Scheduler(基于任务图来实现)
提高效率的核心是threading stealing,保证cpu的效率
七、小结
要使用TBB进行并行化,首先程序员要知道哪些是可以并行化;其次,要熟悉TBB并行化的框架(主要是泛型编程);再次,程序员要大概知道
并行算法的执行步骤;最后,利用TBB的组件,实现并行化的算法。总体上来说,还是不太好用的
发表评论
-
camunda 源代码解析(一)
2020-03-06 17:53 3000壹 基本概念 一、任 ... -
spring cloud gateway 分析一 主流程和层次
2020-02-14 19:27 559一、debug的调用栈如下: DispatcherHand ... -
区块链技术概览
2017-12-05 16:47 1533区块链技术概览 一、 ... -
区块链技术概览
2017-12-05 16:44 23写道 区块链技术概览 ... -
c++以太坊编译
2017-12-04 16:22 729c++以太坊编译 https://github.com/ ... -
编译solc
2017-12-01 17:27 3653git clone https://github.com/ ... -
基于camunda的工作流开发
2017-07-11 09:21 14883一、定义 工作流(Wor ... -
服务端相关技术总结
2017-06-16 10:38 436服务端相关技术总结 在实际产品中,主要涉及到的计算 ... -
django源代码解析
2017-06-08 11:12 910一、wsgi: webserver与app ... -
web开发java VS python
2017-06-07 17:38 1098一、基本概念和知识点 1、web server:实现了ht ... -
spring4 系列一 概览
2017-05-03 14:28 518零、前言 java是静态类型语言,为了能达到动态类型语言的 ... -
yarn 概述
2017-01-16 16:36 460yarn 概述 hdfs上面的资源管理和计算框架 ... -
hdfs 概述
2017-01-16 16:24 670hdfs 简单说是分布式的文件系统 一、hd ... -
机器学习知识梳理二
2017-01-09 17:36 586常见模型和算法 一 ... -
几个概念
2016-11-16 22:18 582计算机=计算+信息程序 ... -
继承环境下java初始化顺序
2016-08-15 14:27 376一、示例代码 package javaDemo; cl ... -
mysql和存储引擎知识点整理
2016-06-15 14:36 503mysql和存储引擎知识点整理 基本概念: 1 ... -
架构设计思考
2016-04-13 21:05 689架构设计思考 一个 ... -
Cocos2dx android 部分代码的理解
2013-12-25 15:38 2745Cocos2dx android 部分代码的理解 ... -
关于cocos2dx的主循环
2013-08-02 15:32 1377关于cocos2dx的主循环 1、调用栈 cocos2 ...
相关推荐
**Intel Threading Building Blocks (TBB) 线程构建模块** Intel Threading Building Blocks (TBB) 是Intel公司推出的一款强大的开源库,专门用于帮助C++开发者进行高效的并行编程。TBB的设计目标是简化多核处理器...
根据提供的文件信息,我们可以深入探讨Intel® Threading Building Blocks (TBB) 的相关内容与关键知识点。尽管提供的部分内容主要涉及法律声明和技术文档的标准免责条款,并没有直接包含技术细节,但基于标题、描述...
TBB(Thread Building Blocks)是由Intel开发的一个开源库,全称为“线程构建模块”。它旨在提供一种高效、灵活的方式来管理和利用多核处理器的并行计算能力,使开发者能够更容易地编写出高性能、可扩展的多线程应用...
TBB,Thread Building Blocks,线程构建模块,是Intel公司开发的并行编程开发的工具。 OSCON 上,Intel 宣布,Threading Building Blocks,Intel 众多软件开发工具中的一个,open source了。协议是 GPLv2。 TBB 获得过...
书名《Pro TBB C++ Parallel Programming with Threading Building Blocks》指出了本书的主要内容是使用Threading Building Blocks (TBB) 进行C++并行编程。Threading Building Blocks 是一个由Intel开发的C++模板库...
在IT领域,尤其是在C/C++多线程编程中,Intel Threading Building Blocks(简称TBB)是一个备受赞誉的工具库,它为并发编程提供了一套现代、工业级的解决方案。以下将深入探讨Intel TBB的核心概念、优势以及其在多核...
Intel Threading Building Blocks(简称TBB)是英特尔推出的一个C++模板库,旨在简化多线程编程。它的核心设计思想是让程序员专注于程序的任务本身,而不是底层线程管理的复杂性。这一点对于现代多核处理器环境下...
**Intel TBB (Threading Building Blocks)** 是一个开源库,由Intel公司开发,主要用于C++编程中的并行计算。TBB提供了一套丰富的模板类和函数,帮助开发者编写高效的多线程程序,使得程序员可以专注于解决算法问题...
TBB库,全称为Threading Building Blocks,是由Intel公司开发的一款高效、易用的多线程编程库。它为C++程序员提供了一组丰富的模板类和函数,使得在多核处理器上实现并行计算变得简单而高效。20150424版本的TBB库是...
《Intel Threading Building Blocks Tutorial》是一份详细的指南,旨在教授...通过深入学习和实践《Intel Threading Building Blocks Tutorial》,开发者能够掌握TBB的精髓,开发出在现代多核系统中运行高效的软件。
Intel Thread Building Blocks (TBB) 很好地解决了上述问题: a)TBB提供C++模版库,用户不必关注线程,而专注任务本身。 b)抽象层仅需很少的接口代码,性能上毫不逊色。 c)灵活地适合不同的多核平台。 d)线程库...
例如,OpenMP是一种通过扩展现有编程语言来表达并行性的方法,而Intel Threading Building Blocks (TBB)则是最近由Intel发布的一个库,它为C++增加了高级别的并行编程技术支持。 #### OpenMP与TBB简介 - **OpenMP*...
TBB,Thread Building Blocks,线程构建模块,是Intel公司开发的并行编程开发的工具。 OSCON 上,Intel 宣布,Threading Building Blocks,Intel 众多软件开发工具中的一个,open source了。协议是 GPLv2。 TBB 获得过...