IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    TBB 入门

    一根稻草发表于 2015-05-17 00:00:00
    love 0
    1. 简介
    2. 应用场景
    3. 配置
    4. 实例
    5. C++相关特性
    6. 相关资料

    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

    ——wikipedia

    2. 应用场景


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

    3. 配置


    TBB当前最新版本是4.3,download

    1. Linux平台

    - 下载:源码:tbb43_20150424oss_src.tgz
    - 解压:tar -xzvf tbb43_20150424oss_src.tgz
    - 编译:cd tbb43_20150424oss && make
    - 安装:cd build/linux_ia32_gcc_cc4.6_libc2.15_kernel3.13.0_release && echo " . `pwd`/tbbvars.sh" >> ~/.bashrc
    

    安装过程中用到了.bashrc文件和source命令

    .bashrc

        The individual per-interactive-shell startup file. 这个文件主要保存个人的一些个性化设置,如命令别名、路径等,在启动bash时会加载执行这个文件
    

    source命令

        也称为“点命令”,也就是一个点符号(.)。source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
    
        用法: 
        source filename 或 . filename
    

    2. Windows平台

    - 下载: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
        #includetbb.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" <

    1. lambda表达式

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

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

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

        []{cout<<"hello world from lambda!"<

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

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

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

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

    2. placement new

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

      #include 
      #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;
      }
    

    6. 相关资料


    • 官网
    • 文档
    • 运算符重载
    • C++11 lambda
    • Lambda表达式语法
    • c++ 11
    • placement new
    • placement new example


沪ICP备19023445号-2号
友情链接