TBB的学习

1. TBB简介

TBB ( Thread Building Blocks, 线程构建模块) 是Intel公司开发的并行编程开发的工具。它支持Windows,OS X, Linux平台,支持的编译器有Visual C++ (version 8.0 or higher, on Windows only), Intel C++ Compiler (version 11.1 or higher) or the GNU Compiler Collection (gcc).

TBB is a collection of components for parallel programming:

  • Basic algorithms: parallel_for, parallel_reduce, parallel_scan
  • Advanced algorithms: parallel_while, parallel_do, parallel_pipeline, parallel_sort
  • Containers: concurrent_queue, concurrent_priority_queue, concurrent_vector, concurrent_hash_map
  • Scalable memory allocation: scalable_malloc, scalable_free, scalable_realloc, scalable_calloc, scalable_allocator, cache_aligned_allocator
  • Mutual exclusion: mutex, spin_mutex, queuing_mutex, spin_rw_mutex, queuing_rw_mutex, recursive_mutex
  • Atomic operations: fetch_and_add, fetch_and_increment, fetch_and_decrement, compare_and_swap, fetch_and_store
  • Timing: portable fine grained global time stamp
  • Task Scheduler: direct access to control the creation and activation of tasks

2. 应用场景

  1. 数据包处理: 如 network router emulator
  2. 图像处理,和OPENCV,IPP一块使用,如 IPP with TBB
  3. 任何可并行的地方

3. 配置

1. 下载地址:https://www.threadingbuildingblocks.org/download

下载:windows release版tbb43_20150424oss_win.zip
- 配置环境变量PATH,保证运行时找到dll
- 在TBB应用工程中添加tbb包含目录,即tbb相关头文件
- 在TBB应用工程中添加tbb库目录,即tbb的lib文件,注意32位和64位有分别的目录

4. 实例

问题:查找一个范围内的所有素数,子问题是判断一个数是不是素数,而且每个数字的判断互不影响,所以可以用并行算法

  find_prime.cc

/*
    ** find_prime.cc
    ** g++ find_prime.cc -ltbb -lrt -o find_prime
    ** -ltbb for tbb library
    ** -lrt for tbb::tick_count::now() using clock_gettime()
    */
    #include<iostream>
    #include<tbb/tbb.h>
    using namespace std;
    using namespace tbb;
    int is_prime(int x)
    {
        int i;
        if (x <= 1) {       /*1不是質數,且不考慮負整數與0,故輸入x<=1時輸出為假 */
            return 0;
        }
        for (i = 2; i * i <= x; ++i) {
            if (x % i == 0) {   /*若整除時輸出為假,否則輸出為真 */
                return 0;
            }
        }
        return 1;
    }
    class FindPrime {
     public:
        void operator() (const blocked_range < size_t > &r)const {
            for (size_t i = r.begin(); i != r.end(); ++i) {
                if (is_prime(i)) {
                    cout << i << endl;
                }
            }
        }
    };
    int main(int argc, char *argv[])
    {
        size_t end = 100;
        if (argc > 1 && atoi(argv[1]) > 0) {
            end = atoi(argv[1]);
        }
        parallel_for(blocked_range < size_t > (0, end), FindPrime());
        return 0;
    }

编译

  g++ find_prime.cc -ltbb -lrt -o find_prime

5. C++相关特性

0. operator overloading

parallel_for第二参数是一个类A的实例对象,该类A要重载操作符 () .

对于

	class Test{
	public:
		void operator()(const int &i) const{
			cout<<"operation with i" <<endl;
		}
	};
第一个const保证i不被改变,第二个const保证调用对象不被改变。
使用方法
	Test t;
	t(110);

1. lambda表达式

匿名函数在C++11中引用,语法是

    [capture子句](参数列表)mutable throw() -> int{函数体}

最简单的一个例子,没有参数,没有异常处理,没有返回类型(自动推断)

    []{cout<<"hello world from lambda!"<<endl;}();

最后的 () 是对匿名函数的调用,分开来看是这样的,首先定义一个函数指针

    typedef void (*func)();
    func f = []{cout<<"hello world from lambda!"<<endl;};
    f();

capture子句主要有两个符号 = , &= 表示以传值的方式传递参数, & 表示以引用的方式(传地址)传递参数,这两个符号可以单独使用,也可以组合使用, & 后面还可以跟一个变量,只修饰它。

	[]  // 没有定义任何变数。使用未定义变数会导致错误。
	[x, &y] // x以传值方式传入(预设),y以传地址方式传入。
	[&]   // 任何被使用到的外部变数皆隐式地以地址方式加以引用。
	[=]   // 任何被使用到的外部变数皆隐式地以传值方式加以引用。
	[&, x]   // x显示地以传值方式加以引用。其馀变数以地址方式加以引用。
	[=, &z]   // z显示地以地址方式加以引用。其馀变数以传值方式加以引用。

2. placement new

所谓placement new就是在用户指定的内存位置上构建新的对象,这个构建过程不需要额外分配内存,只需要调用对象的构造函数即可。

Task Scheduler 库会用到这一特性

  #include <iostream>
  #include "tbb/tbb.h"
  using namespace tbb;
  using namespace std;

  class first_task:public task {
   public:
    task * execute() {
        cout << "Hello World!\n";
        return NULL;
    }
  };

  int main()
  {
    task_scheduler_init init(task_scheduler_init::automatic);
    first_task & f1 = *new(tbb::task::allocate_root())first_task();
    tbb::task::spawn_root_and_wait(f1);
    return 0;
  }

endl;

参考博客:http://www.tuicool.com/articles/R3uu22

时间: 2024-12-21 23:27:02

TBB的学习的相关文章

TBB 学习笔记

#include <tbb/task_scheduler_init.h> #include <tbb/blocked_range.h> #include <tbb/parallel_for.h> #include <iostream> class ApplyFoo { private: float *const my_a; public: void operator()(const tbb::blocked_range<size_t>&r

OpenCV2学习笔记(二十一):GPU模块小记

接触一下OpenCV里一个之前没有接触的模块:GPU.这里只是根据教程和大家简单交流一下,欢迎大家批评指正. 注:在使用GPU模块之前,需要确认在使用CMake编译OpenCV时,勾选了选项WITH_CUDA和WITH_TBB使其生效生效. 若以上配置已经完成,在使用GPU模块的函数之前,还做一下检查:调用函数gpu::getCudaEnabledDeviceCount,如果你在使用的OpenCV模块编译时不支持GPU,这个函数返回值为0:否则返回值为已安装的CUDA设备的数量. OpenCV的

值得学习的C/C++开源框架(转)

值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力.Webbench使用C语言编写, 代码实在太简洁,源码加起来不到600行. 下载链接:http://home.tiscali.cz/~cz210552/webbench.html - 2. Tinyhttpd tinyhttpd是一个超轻量型Ht

值得学习的C语言开源项目

- 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力.Webbench使用C语言编写, 代码实在太简洁,源码加起来不到600行. 下载链接:http://home.tiscali.cz/~cz210552/webbench.html - 2. Tinyhttpd tinyhttpd是一个超轻量型Http Server,使用C

C++的一些不错开源框架,可以学习和借鉴

larryjiang 我的文章 我的文档 我的文集 我的收藏 我的草稿 我的微博 我的投票 我的活动 我的相册 我的日历 退出登录 × 查看26条@我的微博 查看1条系统消息 查看44条@我的微博 创建文章 创建活动 创建相册 创建投票 创建文集 创建定时短信 手机KM 频道 研发月报 腾讯月刊 Q益平台 微爱益起来 职业发展 总办交流 KM周刊 乐问周刊 应用 活动 投票 相册 文集 幻灯片 祝福卡 定时短信 达人堂 实验室 期刊 工作圈 我的K吧 K吧排序 浏览K吧 | 创建K吧 KM平台组

TBB入门

获取TBB TBB的官方网站在http://threadingbuildingblocks.org/,可以在它的Downloads页面里找到Commercial Aligned Release,最新版是tbb20_014,Windows上开发需要下载tbb20_014oss_src.tar.gz和tbb20_014oss_win.tar.gz.其它支持的平台有linux和mac. 将下载后的压缩包解压后,tbb20_014oss_win.tar.gz里有: tbb20_20070927oss_w

学习OpenCV——OpenMP

转自:http://www.cnblogs.com/yangyangcv/archive/2012/03/23/2413335.html openMP的一点使用经验 最近在看多核编程.简单来说,由于现在电脑CPU一般都有两个核,4核与8核的CPU也逐渐走入了寻常百姓家,传统的单线程编程方式难以发挥多核CPU的强大功能,于是多核编程应运而生.按照我的理解,多核编程可以认为是对多线程编程做了一定程度的抽象,提供一些简单的API,使得用户不必花费太多精力来了解多线程的底层知识,从而提高编程效率.这两天

ruby学习笔记(1)-puts,p,print的区别

ruby学习笔记-puts,p,print的区别 共同点:都是用来屏幕输出的. 不同点:puts 输出内容后,会自动换行(如果内容参数为空,则仅输出一个换行符号):另外如果内容参数中有转义符,输出时将先处理转义再输出p 基本与puts相同,但不会处理参数中的转义符号print 基本与puts相同,但输出内容后,不会自动在结尾加上换行符 1 2 3 4 5 6 7 s = "aaaa\nbb\tbb" p s p "****************" puts s p

TLD之学习篇(四)

TLD之学习篇(四) TLD之扯淡篇(一).TLD之检测篇(二).TLD之跟踪篇(三) 这一部分是TLD算法的核心之处,有了前面两篇的铺垫,终于可以毫无顾忌的说说这一部分了.不过,还有一座大山,程序的初始化,这是程序运行的铺垫,内容很多--. 初始化 在run_tld.cpp中,一旦你选的要跟踪的目标box后便会调用初始化init: tld.init(last_gray,box,bb_file);//初始目标位置存储在box 内容太多,大伙看下面程序中标出的9点吧,其中3.5.8三点已经讲过啦,