Intel TBB简介及在Windows7 VS2013上源码的编译过程

Intel TBB(Intel Threading Building Blocks)是Intel线程构建块开源库,它的License是Apache 2.0.

         Intel TBB是一种用于并行编程的基于C++语言的框架,它是一套C++模板库。它提供了大量特性,具有比线程更高程度的抽象。

         Intel TBB可以在Windows、Linux和OSX上运行,支持Intel、Microsoft和GNU工具。

         Intel TBB特性:

         (1)、与线程不同,你可以对任务使用更高程度的抽象。Intel声称,在Linux系统上,启动和结束任务的速度是对线程执行相同操作的18倍;

(2)、Intel TBB附带了一个任务调度程序,该程序可以跨多个逻辑和物理内核高效地处理负载平衡。Intel TBB 中的默认任务调度策略不同于大多数线程调度程序所拥有的轮询策略;

(3)、Intel TBB提供了一些可直接使用的线程安全容器;

(4)、可以使用通用的并行算法,如parallel_for和parallel_reduce;

(5)、模板类atomic中提供了无锁(Lock-free,也称为mutex-free)并发编程支持。这种支持使得Intel TBB适合用于高性能的应用程序,因为Intel TBB可以锁定和解除锁定互斥体 (mutex);

Intel TBB注意事项:

(1)、要运行Intel TBB程序,则必须正确地初始化任务调度程序;

(2)、Intel TBB提供了一个名为task_list容器,可以将它用作一个任务集合;

(3)、每个父任务都使用allocate_child函数调用创建一个子任务;

(4)、在衍生出任何子任务之前,父任务必须调用set_ref_count。如果没有这么做,则会导致出现未定义的行为。如果打算衍生一些子任务,然后等待它们完成,那么count的值必须为子任务数+ 1;否则,count会等于子任务的数量;

(5)、最好由调度程序决定最佳的线程数量;

         在Windows7 VS2013上编译Intel TBB源代码操作步骤:

         (1)、从 https://www.threadingbuildingblocks.org/download 下载源代码tbb2017_20161128oss_src.tgz ;

         (2)、新建三个空工程,分别为tbb、tbbmalloc、tbbmalloc_proxy,项目配置类型为动态库(.dll),其中tbb、tbbmalloc项目有汇编文件的参与,因此需要在tbb、tbbmalloc工程加入汇编文件的支持,步骤如下:

         选中tbb或tbbmalloc--> 生成依赖项 --> 生成自定义 --> 勾选masm,点击确定;

         (3)、将相应文件加入到工程中;

         (4)、生成tbb.def文件:这里有三种简单方法(tbb.def可以由CMake通过win64-tbb-export.def和win64-tbb-export.lst文件产生):

A、在tbb2017_20161128oss_src/build/vs2012目录下,打开makefile.sln,升级到vs2013版本,编译tbb工程,期间便会生成tbb.def文件;

B、从 https://github.com/wjakob/tbb 下载Intel TBB,其提供在Windows下用cmake-gui.exe生成vs2013解决方案,编译tbb工程,期间也会生成tbb.def文件;

C、从https://www.threadingbuildingblocks.org/download下载二进制文件tbb2017_20161128oss_win,在lib/intel64/vc**目录内也有tbb.def文件;

(5)、将tbb.def文件加入到tbb工程属性 --> 链接器 --> 命令行 --> 其它选项中;

(6)、生成tbbmalloc.def文件:与以上(4)、(5)中步骤一致;

(7)、三个工程编译顺序:先tbb,然后tbbmalloc,最后再是tbbmalloc_proxy,后者会依赖前者;

(8)、新创建一个IntelTBB_Test控制台工程,测试代码如下:

#include "funset.hpp"
#include <iostream>
#include <tbb/tbb.h>

// reference: http://www.ibm.com/developerworks/cn/aix/library/au-intelthreadbuilding/
class first_task : public tbb::task {
public:
	tbb::task* execute() {
		fprintf(stderr, "Hello World!\n");
		return nullptr;
	}
};

int test_IntelTBB_1()
{
	tbb::task_scheduler_init init(tbb::task_scheduler_init::automatic);
	first_task& f1 = *new(tbb::task::allocate_root()) first_task();
	tbb::task::spawn_root_and_wait(f1);

	return 0;
}

class first_task_2 : public tbb::task {
public:
	tbb::task* execute() {
		fprintf(stderr, "Hello World!\n");
		tbb::task_list list1;
		list1.push_back(*new(allocate_child()) first_task_2());
		list1.push_back(*new(allocate_child()) first_task_2());
		set_ref_count(3); // 2 (1 per child task) + 1 (for the wait) 
		spawn_and_wait_for_all(list1);
		return nullptr;
	}
};

int test_IntelTBB_2()
{
	first_task& f1 = *new(tbb::task::allocate_root()) first_task();
	tbb::task::spawn_root_and_wait(f1);

	return 0;
}

class say_hello {
public:
	say_hello(const char* str) : message(str) {  }
	void operator( ) () const {
		fprintf(stderr, "%s\n", message);
	}
private:
	const char* message;
};

int test_IntelTBB_3()
{
	tbb::task_group tg;
	tg.run(say_hello("child 1")); // spawn task and return
	tg.run(say_hello("child 2")); // spawn another task and return 
	tg.wait(); // wait for tasks to complete

	return 0;
}

GitHub:https://github.com/fengbingchun/Face_Test
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fengbingchun/article/details/58281829
个人分类: OpenMP/Intel TBB
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭