首先下载:
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编译模式
- /*
- Copyright2005-2008IntelCorporation.AllRightsReserved.
- ThisfileispartofThreadingBuildingBlocks.
- ThreadingBuildingBlocksisfreesoftware;youcanredistributeit
- and/ormodifyitunderthetermsoftheGNUGeneralPublicLicense
- version2aspublishedbytheFreeSoftwareFoundation.
- ThreadingBuildingBlocksisdistributedinthehopethatitwillbe
- useful,butWITHOUTANYWARRANTY;withouteventheimpliedwarranty
- ofMERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
- GNUGeneralPublicLicenseformoredetails.
- YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense
- alongwithThreadingBuildingBlocks;ifnot,writetotheFreeSoftware
- Foundation,Inc.,51FranklinSt,FifthFloor,Boston,MA02110-1301USA
- Asaspecialexception,youmayusethisfileaspartofafreesoftware
- librarywithoutrestriction.Specifically,ifotherfilesinstantiate
- templatesorusemacrosorinlinefunctionsfromthisfile,oryoucompile
- thisfileandlinkitwithotherfilestoproduceanexecutable,this
- filedoesnotbyitselfcausetheresultingexecutabletobecoveredby
- theGNUGeneralPublicLicense.Thisexceptiondoesnothowever
- invalidateanyotherreasonswhytheexecutablefilemightbecoveredby
- theGNUGeneralPublicLicense.
- */
- //
- //Exampleprogramthatreadsafileoftextandchangesthefirstletter
- //ofeachwordtouppercase.
- //
- #include"tbb/pipeline.h"
- #include"tbb/tick_count.h"
- #include"tbb/task_scheduler_init.h"
- #include<cstring>
- #include<cstdlib>
- #include<cstdio>
- #include<cctype>
- usingnamespacestd;
- //!Bufferthatholdsblockofcharactersandlastcharacterofpreviousbuffer.
- classMyBuffer{
- staticconstsize_tbuffer_size=10000;
- char*my_end;
- //!storage[0]holdsthelastcharacterofthepreviousbuffer.
- charstorage[1+buffer_size];
- public:
- //!Pointertofirstcharacterinthebuffer
- char*begin(){returnstorage+1;}
- constchar*begin()const{returnstorage+1;}
- //!Pointertoonepastlastcharacterinthebuffer
- char*end()const{returnmy_end;}
- //!Setendofbuffer.
- voidset_end(char*new_ptr){my_end=new_ptr;}
- //!Numberofbytesabuffercanhold
- size_tmax_size()const{returnbuffer_size;}
- //!Numberofbytesappendedtobuffer.
- size_tsize()const{returnmy_end-begin();}
- };
- classMyInputFilter:publictbb::filter{
- public:
- staticconstsize_tn_buffer=8;
- MyInputFilter(FILE*input_file_);
- private:
- FILE*input_file;
- size_tnext_buffer;
- charlast_char_of_previous_buffer;
- MyBufferbuffer[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_tn=fread(b.begin(),1,b.max_size(),input_file);
- if(!n){
- //endoffile
- returnNULL;
- }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;
- }
- }
- //!Filterthatchangesthefirstletterofeachwordfromlowercasetouppercase.
- classMyTransformFilter:publictbb::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);
- intprev_char_is_space=b.begin()[-1]=='';
- for(char*s=b.begin();s!=b.end();++s){
- if(prev_char_is_space&&islower((unsignedchar)*s))
- *s=toupper(*s);
- prev_char_is_space=isspace((unsignedchar)*s);
- }
- return&b;
- }
- //!Filterthatwriteseachbuffertoafile.
- classMyOutputFilter:publictbb::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);
- returnNULL;
- }
- staticintNThread=tbb::task_scheduler_init::automatic;
- staticconstchar*InputFileName="input.txt";
- staticconstchar*OutputFileName="output.txt";
- staticboolis_number_of_threads_set=false;
- voidUsage()
- {
- fprintf(stderr,"Usage:\ttext_filter[input-file[output-file[nthread]]]\n");
- }
- intParseCommandLine(intargc,char*argv[]){
- //Parsecommandline
- if(argc>4){
- Usage();
- return0;
- }
- 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,"nthreadsetto%d,butmustbeatleast1\n",NThread);
- return0;
- }
- is_number_of_threads_set=true;//Numberofthreadsissetexplicitly
- }
- return1;
- }
- intrun_pipeline(intnthreads)
- {
- FILE*input_file=fopen(InputFileName,"r");
- if(!input_file){
- perror(InputFileName);
- Usage();
- return0;
- }
- FILE*output_file=fopen(OutputFileName,"w");
- if(!output_file){
- perror(OutputFileName);
- return0;
- }
- //Createthepipeline
- tbb::pipelinepipeline;
- //Createfile-readingwritingstageandaddittothepipeline
- MyInputFilterinput_filter(input_file);
- pipeline.add_filter(input_filter);
- //Createcapitalizationstageandaddittothepipeline
- MyTransformFiltertransform_filter;
- pipeline.add_filter(transform_filter);
- //Createfile-writingstageandaddittothepipeline
- MyOutputFilteroutput_filter(output_file);
- pipeline.add_filter(output_filter);
- //Runthepipeline
- tbb::tick_countt0=tbb::tick_count::now();
- pipeline.run(MyInputFilter::n_buffer);
- tbb::tick_countt1=tbb::tick_count::now();
- //Removefiltersfrompipelinebeforetheyareimplicitlydestroyed.
- pipeline.clear();
- fclose(output_file);
- fclose(input_file);
- if(is_number_of_threads_set){
- printf("threads=%dtime=%g\n",nthreads,(t1-t0).seconds());
- }else{
- if(nthreads==1){
- printf("serialruntime=%g\n",(t1-t0).seconds());
- }else{
- printf("parallelruntime=%g\n",(t1-t0).seconds());
- }
- }
- return1;
- }
- intmain(intargc,char*argv[]){
- if(!ParseCommandLine(argc,argv))
- return1;
- if(is_number_of_threads_set){
- //Starttaskscheduler
- tbb::task_scheduler_initinit(NThread);
- if(!run_pipeline(NThread))
- return1;
- }else{//Numberofthreadswasn'tsetexplicitly.Runserialandparallelversion
- {//serialrun
- tbb::task_scheduler_initinit_serial(1);
- if(!run_pipeline(1))
- return1;
- }
- {//parallelrun(numberofthreadsisselectedautomatically)
- tbb::task_scheduler_initinit_parallel;
- if(!run_pipeline(0))
- return1;
- }
- }
- return0;
- }
第二个程序,对应debug模式,带上tbb_debug.lib:
- #include"tbb/task_scheduler_init.h"
- #include"tbb/blocked_range.h"
- #include"tbb/parallel_for.h"
- //链接tbb_debug.lib
- //#pragmacomment(lib,"tbb_debug.lib")
- usingnamespacetbb;
- //对每个Item执行该操作
- voidFoo(floatvalue)
- {
- printf("%.2f\n",value);
- }
- classApplyFoo
- {
- float*constmy_a;
- public:
- voidoperator()(constblocked_range<size_t>&r)const
- {
- float*a=my_a;
- for(size_ti=r.begin();i!=r.end();++i)
- Foo(a[i]);
- }
- ApplyFoo(floata[]):my_a(a){}
- };
- int_tmain(intargc,_TCHAR*argv[])
- {
- //创建taskscheduler
- //task_scheduler_init支持一个参数,以指定使用的线程数
- task_scheduler_initinit;
- floata[100];
- for(inti=0;i<100;i++)
- a[i]=(float)i;
- //TBB会把数组分成若干的block
- //对block调用ApplyFoo这个functor
- parallel_for(blocked_range<size_t>(0,100),ApplyFoo(a));
- return0;
- }