intel线程库tbb的使用

[size=small]首先下载:

http://www.threadingbuildingblocks.org/uploads/77/111/2.1/tbb21_20080605oss_win.zip

当前是2.1版本

解压到c盘,打开vs2005,设置vc++的项目目录

include:

C:\tbb21oss_win\include

执行文件:

C:\tbb21oss_win\ia32\vc8\bin

库文件:

C:\tbb21oss_win\ia32\vc8\lib

最后设置 我的电脑--环境变量设置

添加下面到path部分的最前面,记得加上一个“;”:C:\tbb21oss_win\ia32\vc8\bin

然后添加一个变量:

TBB21_INSTALL_DIR 为C:\tbb21oss_win

开启vs2005的命令行工具,进入到C:\tbb21oss_win\ia32\vc8\bin路径,执行tbbvars.bat文件

可以开始第一个程序了,记得带上tbb.lib对应的是release编译模式

/* 
    Copyright 2005-2008 Intel Corporation.  All Rights Reserved.

This file is part of Threading Building Blocks.

Threading Building Blocks is free software; you can redistribute it 
    and/or modify it under the terms of the GNU General Public License 
    version 2 as published by the Free Software Foundation.

Threading Building Blocks is distributed in the hope that it will be 
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    GNU General Public License for more details.

You should have received a copy of the GNU General Public License 
    along with Threading Building Blocks; if not, write to the Free Software 
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

As a special exception, you may use this file as part of a free software 
    library without restriction.  Specifically, if other files instantiate 
    templates or use macros or inline functions from this file, or you compile 
    this file and link it with other files to produce an executable, this 
    file does not by itself cause the resulting executable to be covered by 
    the GNU General Public License.  This exception does not however 
    invalidate any other reasons why the executable file might be covered by 
    the GNU General Public License. 
*/

// 
// Example program that reads a file of text and changes the first letter 
// of each word to upper case. 
//  
#include "tbb/pipeline.h" 
#include "tbb/tick_count.h" 
#include "tbb/task_scheduler_init.h" 
#include <cstring> 
#include <cstdlib> 
#include <cstdio> 
#include <cctype>

using namespace std;

//! Buffer that holds block of characters and last character of previous buffer. 
class MyBuffer { 
    static const size_t buffer_size = 10000; 
    char* my_end; 
    //! storage[0] holds the last character of the previous buffer. 
    char storage[1+buffer_size]; 
public: 
    //! Pointer to first character in the buffer 
    char* begin() {return storage+1;} 
    const char* begin() const {return storage+1;} 
    //! Pointer to one past last character in the buffer 
    char* end() const {return my_end;} 
    //! Set end of buffer. 
    void set_end( char* new_ptr ) {my_end=new_ptr;} 
    //! Number of bytes a buffer can hold 
    size_t max_size() const {return buffer_size;} 
    //! Number of bytes appended to buffer. 
    size_t size() const {return my_end-begin();} 
};

class MyInputFilter: public tbb::filter { 
public: 
    static const size_t n_buffer = 8; 
    MyInputFilter( FILE* input_file_ ); 
private: 
    FILE* input_file; 
    size_t next_buffer; 
    char last_char_of_previous_buffer; 
    MyBuffer buffer[n_buffer]; 
    /*override*/ void* operator()(void*); 
};

MyInputFilter::MyInputFilter( FILE* input_file_ ) :  
    filter(/*is_serial=*/true), 
    next_buffer(0), 
    input_file(input_file_), 
    last_char_of_previous_buffer(‘ ‘) 
{  
}

void* MyInputFilter::operator()(void*) { 
    MyBuffer& b = buffer[next_buffer]; 
    next_buffer = (next_buffer+1) % n_buffer; 
    size_t n = fread( b.begin(), 1, b.max_size(), input_file ); 
    if( !n ) { 
        // end of file 
        return NULL; 
    } else { 
        b.begin()[-1] = last_char_of_previous_buffer; 
        last_char_of_previous_buffer = b.begin()[n-1]; 
        b.set_end( b.begin()+n ); 
        return &b; 
    } 
}

//! Filter that changes the first letter of each word from lower case to upper case. 
class MyTransformFilter: public tbb::filter { 
public: 
    MyTransformFilter(); 
    /*override*/void* operator()( void* item ); 
};

MyTransformFilter::MyTransformFilter() :  
    tbb::filter(/*ordered=*/false)  
{}

/*override*/void* MyTransformFilter::operator()( void* item ) { 
    MyBuffer& b = *static_cast<MyBuffer*>(item); 
    int prev_char_is_space = b.begin()[-1]==‘ ‘; 
    for( char* s=b.begin(); s!=b.end(); ++s ) { 
        if( prev_char_is_space && islower((unsigned char)*s) ) 
            *s = toupper(*s); 
        prev_char_is_space = isspace((unsigned char)*s); 
    } 
    return &b;   

          
//! Filter that writes each buffer to a file. 
class MyOutputFilter: public tbb::filter { 
    FILE* my_output_file; 
public: 
    MyOutputFilter( FILE* output_file ); 
    /*override*/void* operator()( void* item ); 
};

MyOutputFilter::MyOutputFilter( FILE* output_file ) :  
    tbb::filter(/*is_serial=*/true), 
    my_output_file(output_file) 

}

void* MyOutputFilter::operator()( void* item ) { 
    MyBuffer& b = *static_cast<MyBuffer*>(item); 
    fwrite( b.begin(), 1, b.size(), my_output_file ); 
    return NULL; 
}

static int NThread = tbb::task_scheduler_init::automatic; 
static const char* InputFileName = "input.txt"; 
static const char* OutputFileName = "output.txt"; 
static bool is_number_of_threads_set = false;

void Usage() 

    fprintf( stderr, "Usage:\ttext_filter [input-file [output-file [nthread]]]\n"); 
}

int ParseCommandLine(  int argc, char* argv[] ) { 
    // Parse command line 
    if( argc> 4 ){ 
        Usage(); 
        return 0; 
    } 
    if( argc>=2 ) InputFileName = argv[1]; 
    if( argc>=3 ) OutputFileName = argv[2]; 
    if( argc>=4 ) { 
        NThread = strtol(argv[3],0,0); 
        if( NThread<1 ) { 
            fprintf(stderr,"nthread set to %d, but must be at least 1\n",NThread); 
            return 0; 
        } 
        is_number_of_threads_set = true; //Number of threads is set explicitly 
    } 
    return 1; 
}

int run_pipeline( int nthreads ) 

    FILE* input_file = fopen(InputFileName,"r"); 
    if( !input_file ) { 
        perror( InputFileName ); 
        Usage(); 
        return 0; 
    } 
    FILE* output_file = fopen(OutputFileName,"w"); 
    if( !output_file ) { 
        perror( OutputFileName ); 
        return 0; 
    }

// Create the pipeline 
    tbb::pipeline pipeline;

// Create file-reading writing stage and add it to the pipeline 
    MyInputFilter input_filter( input_file ); 
    pipeline.add_filter( input_filter );

// Create capitalization stage and add it to the pipeline 
    MyTransformFilter transform_filter;  
    pipeline.add_filter( transform_filter );

// Create file-writing stage and add it to the pipeline 
    MyOutputFilter output_filter( output_file ); 
    pipeline.add_filter( output_filter );

// Run the pipeline 
    tbb::tick_count t0 = tbb::tick_count::now(); 
    pipeline.run( MyInputFilter::n_buffer ); 
    tbb::tick_count t1 = tbb::tick_count::now();

// Remove filters from pipeline before they are implicitly destroyed. 
    pipeline.clear();

fclose( output_file ); 
    fclose( input_file );

if (is_number_of_threads_set) { 
        printf("threads = %d time = %g\n", nthreads, (t1-t0).seconds()); 
    } else { 
        if ( nthreads == 1 ){ 
            printf("serial run   time = %g\n", (t1-t0).seconds()); 
        } else { 
            printf("parallel run time = %g\n", (t1-t0).seconds()); 
        } 
    } 
    return 1; 
}

int main( int argc, char* argv[] ) { 
    if(!ParseCommandLine( argc, argv )) 
        return 1; 
    if (is_number_of_threads_set) { 
        // Start task scheduler 
        tbb::task_scheduler_init init( NThread ); 
        if(!run_pipeline (NThread)) 
            return 1; 
    } else { // Number of threads wasn‘t set explicitly. Run serial and parallel version 
        { // serial run 
            tbb::task_scheduler_init init_serial(1); 
            if(!run_pipeline (1)) 
                return 1; 
        } 
        { // parallel run (number of threads is selected automatically) 
            tbb::task_scheduler_init init_parallel; 
            if(!run_pipeline (0)) 
                return 1; 
        } 
    } 
    return 0; 
}

第二个程序,对应debug模式,带上tbb_debug.lib:

#include "tbb/task_scheduler_init.h" 
#include "tbb/blocked_range.h" 
#include "tbb/parallel_for.h"

// 链接tbb_debug.lib 
//#pragma comment(lib, "tbb_debug.lib")

using namespace tbb;

// 对每个Item执行该操作 
void Foo(float value) 

    printf("%.2f\n ", value); 
}

class ApplyFoo 
    { 
        float * const my_a; 
public: 
    void operator () (const blocked_range<size_t> & r) const 
        { 
            float * a = my_a; 
            for (size_t i = r.begin(); i != r.end(); ++ i) 
                Foo(a[i]); 
    }

ApplyFoo(float a[]) : my_a(a) {} 
};

int _tmain(int argc, _TCHAR* argv[]) 

    // 创建task scheduler 
    // task_scheduler_init支持一个参数,以指定使用的线程数 
    task_scheduler_init init; 
    float a[100]; 
    for (int i = 0; i < 100; i ++) 
        a[i] = (float)i; 
    // TBB会把数组分成若干的block 
    // 对block调用ApplyFoo这个functor 
    parallel_for(blocked_range<size_t>(0, 100), ApplyFoo(a)); 
    return 0; 
}

时间: 2025-01-09 03:25:29

intel线程库tbb的使用的相关文章

boost 线程库

http://www.boost.org/Boost的安装step1.从www.boost.org下载boost库 step2 在 tools\build\jam_src目录下 运行build.bat来生成jamstep3 设置环境变量(后面的%PATH%要加) PATH=%boost的绝对路径%\tools\build\jam_src\bin.ntx86;%PATH% PATH=%boost的绝对路径%;%PATH% For Visial Studio 6.0SET MSVC_ROOT="VC

linux线程库

linux 提供两个线程库,Linux Threads 和新的原生的POSIX线程库(NPTL),linux threads在某些情况下仍然使用,但现在的发行版已经切换到NPTL,并且大部分应用已经不在加载linux threads,NPTL更轻量,更高效,也会有那些linux threads遇到的问题. 问题:怎么查看系统正在使用哪种线程库呢? linux线程库

Linux posix线程库总结

由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 目前,pthreads的实现有3种方式: (1)第一,多对一,也就是库实现. (2)第二种,1:1模式. 1:1模式适合CPU密集型的机器.我们知道,进程(线程)在运行中会由于等待某种资源而阻塞,可能是I/O资源,也可能是CPU.在多CPU机器上1:1模式是个很不错的选择.因此1:1的优点就是,能够充分发挥SMP的优势. 这种模式也有它的缺

Java高性能线程库:Jetlang

Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用.该类库不提供远程的消息功能,其设计的宗旨是实现一个内存中的消息传递机制: 主要特点有: All messages to a particular Fiber are delivered sequentially. Components can easily keep state without synchronizing data ac

Arduino线程库ProtoThreads

参考: Arduino线程库ProtoThreads 一个“蝇量级” C 语言协程库

用户态线程库——C语言实现

轮子年年有人造,我们也来凑热闹,参考协程实现,大概有以下几种方法: 1)利用setjmp,longjmp 2)利用ucontext接口函数 3)汇编 (线程无非就是多了个抢占功能,由定时器触发,而非自愿让出运行权限) 因为我写的时候还没看到其他帖子,如果看到了,铁定会用最直观的ucontext接口写的(注意,在macOSX中已经标注为废除,头文件得换做sys/ucontext.h),结果就是我用了汇编来写,但是尽量不用汇编来写整个switch_to调度函数(这样有个明显的坏处,那就是用gas/n

【Jetlang】一个高性能的Java线程库

actor  Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用. .net的MS CCR和Retlang:

C/C++ Posix线程库的封装

经常没事写一些服务器压力测试的工具,如http,mysql,等.说到压力测试,首先想到的应该就是多线程,研究过一段时间的pthread,包括线程锁,在这里发一个自己写的Posix封装. Posix.h 该类作为一个父类,应写一个子类继承他,并重写action方法,action()为所有线程所执行的内容,最后使用Run()开始执行所有线程. #ifndef POSIX_H_ #define POSIX_H_ #include <iostream> #include <pthread.h&g

windows下线程库的使用

下载PTHREAD的WINDOWS开发包 pthreads-w32-2-4-0-release.exe(任何一个版本均可)   http://sourceware.org/pthreads-win32/ ,解压到一个目录. 1.添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录. 2.添加文件引用的lib静态库路径:工程---属性---配置属性---链接器---常规---附加库目录:加上lib文件存放目录.         然后添加