




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、TBB的幾個(gè)特性與線程不同,您可以對(duì)任務(wù)使用更高程度的抽象。Intel 聲稱,在 Linux 系統(tǒng)上,啟動(dòng)和結(jié)束任務(wù)的速度是對(duì)線程執(zhí)行相同操作的 18 倍。Intel TBB 附帶了一個(gè)任務(wù)調(diào)度程序,該程序可以跨多個(gè)邏輯和物理內(nèi)核高效地處理負(fù)載平衡。Intel TBB 中的默認(rèn)任務(wù)調(diào)度策略不同于大多數(shù)線程調(diào)度程序所擁有的輪詢策略。Intel TBB 提供了一些可直接使用的線程安全容器,比如 concurrent_vector 和 concurrent_queue??梢允褂猛ㄓ玫牟⑿兴惴?,如 parallel_for 和 parallel_reduce。模板類 atomic 中提供了無(wú)鎖(Loc
2、k-free,也稱為 mutex-free)并發(fā)編程支持。這種支持使得 Intel TBB 適合用于高性能的應(yīng)用程序,因?yàn)?Intel TBB 可以鎖定和解除鎖定互斥體 (mutex)。這都是用 C+ 實(shí)現(xiàn)的!沒(méi)有進(jìn)行任何擴(kuò)展或使用宏,Intel TBB 只使用這種語(yǔ)言,同時(shí)還使用了大量的模板。上圖的內(nèi)容可以分為以下幾類:l 通用并行算法TBB提供了parallel_for,parallel_while,parallel_reduce等算法,應(yīng)用于不同的并行算法場(chǎng)景l(fā) 并發(fā)容器這是對(duì)常見容器的線程安全版本的實(shí)現(xiàn),同時(shí)考慮到性能要求,提供了細(xì)粒度的鎖機(jī)制,TBB2.0里提供的容器包括hash m
3、ap,vector,queue。l 任務(wù)調(diào)度器:提供了task機(jī)制的封裝l 同步原語(yǔ):提供了原子操作、mutex、lock等同步原語(yǔ)的封裝l 內(nèi)存分配:提供了對(duì)cache機(jī)制更友好的支持parallel_forl 摘要parallel_for是在一個(gè)值域執(zhí)行并行迭代操作的模板函數(shù)。l 語(yǔ)法templateFunc parallel_for( Index first, Index_type last, const Func& f , task_group_context&group ); templateFunc parallel_for( Index first, Index_
4、type last, Index step, const Func&f , task_group_context&group ); template Void parallel_for( const Range& range, const Body& body, , partitioner,task_group_context& group );l 頭文件#include “tbb/parallel_for.h”l 描述parallel_for(first, last,step, f)表示一個(gè)循環(huán)的并行執(zhí)行: for(auto i= first; ila
5、st; i+=step) f(i);example:#include #include using namespace tbb;using namespace std;int main() parallel_for(0,10,(int v)coutv ;); return0;parallel_for原型語(yǔ)義Body:Body(const Body&) 拷貝構(gòu)造Body:Body()析構(gòu)void Body:operator()(Range& range) const對(duì)range對(duì)象應(yīng)用body對(duì)象l描述parallel_for(range, body, partitioner)提
6、供了并行迭代的泛型形式。它表示在區(qū)域的每個(gè)值,并行執(zhí)行body。partitioner選項(xiàng)指定了分割策略。Range類型必須符合Range概念模型。body必須符合下表的要求:采用最后一個(gè)模板以及stl中的vector容器改寫example:#include #include #include #include #include using namespace std;using namespace tbb;typedef vector:iterator IntVecIt;struct body void operator()(const blocked_range&r)const f
7、or(auto i = r.begin(); i!=r.end(); i+) cout*i ; ;int main() vector vec; for(int i=0; i10; i+) vec.push_back(i); parallel_for(blocked_range(vec.begin(), vec.end() , body(); return 0;原型摘要R:R(const R& )構(gòu)造函數(shù)R:R()析構(gòu)函數(shù)bool R:empty() const區(qū)域?yàn)榭辗祷豻urebool R:is_divisible() const 如果區(qū)域可再分,返回tureR:R(R& r
8、, split)將r分為兩個(gè)子區(qū)域Parallel_reducel 摘要parallel_reduce模板在一個(gè)區(qū)域迭代,將由各個(gè)任務(wù)計(jì)算得到的部分結(jié)果合并,得到最終結(jié)果。parallel_reduce對(duì)區(qū)域(range)類型的要求與parallel_for一樣。l 語(yǔ)法templateValue parallel_reduce(const Range& range, const Value& identity, const Func& func, const Reduction& reduction, , partitioner,task_group_cont
9、ext& group ); template void parallel_reduce(const Range& range, const Body& body , partitioner,task_group_context& group );l 頭文件#include “tbb/parallel_reduce.h”原型摘要Value IdentityFunc:operator()的左標(biāo)識(shí)元素Value Func:operator()(const Range& range, const Value& x)累計(jì)從初始值x開始的子區(qū)域的結(jié)果Valu
10、e Reduction:operator()(const Value& x, const Value& y);合并x跟y的結(jié)果l 描述parallel_reduce模板有兩種形式。函數(shù)形式是為方便與lambda表達(dá)式一起使用而設(shè)計(jì)。第二種形式是為了最小化數(shù)據(jù)拷貝。 下面的表格總結(jié)了第一種形式中的identity,func,reduction的類型要求:Parallel_reduce#include #include #include #include using namespace std;using namespace tbb;int main() vector vec; f
11、or(int i=0; i100; i+) vec.push_back(i);int result = parallel_reduce(blocked_rangevector:iterator(vec.begin(), vec.end(), 0, (const blocked_rangevector:iterator& r, int init)-int for(auto a = r.begin(); a!=r.end(); a+) init+=*a; return init; , (int x, int y)-int return x+y; ); coutresult:resulten
12、dl; return 0;了解TBB任務(wù)Intel TBB 基于 任務(wù) 的概念。您需要定義自己的任務(wù),這些任務(wù)是從 tbb:task 中派生的,并使用 tbb/task.h 進(jìn)行聲明。用戶需要在自己的代碼中重寫純虛擬方法 task* task:execute ( )。下面展示了每個(gè) Intel TBB 任務(wù)的一些屬性:當(dāng) Intel TBB 任務(wù)調(diào)度程序選擇運(yùn)行一些任務(wù)時(shí),會(huì)調(diào)用該任務(wù)的 execute 方法。這是入口點(diǎn)。execute 方法會(huì)返回一個(gè) task*,告訴調(diào)度程序?qū)⒁\(yùn)行的下一個(gè)任務(wù)。如果它返回 NULL,那么調(diào)度程序可以自由選擇下一個(gè)任務(wù)。task:task( ) 是虛擬的,不
13、管用戶任務(wù)占用了什么資源,都必須在這個(gè)析構(gòu)函數(shù) (destructor) 中釋放。任務(wù)是通過(guò)調(diào)用 task:allocate_root( ) 來(lái)分配的。主任務(wù)通過(guò)調(diào)用 task:spawn_root_and_wait(task) 來(lái)完成任務(wù)的運(yùn)行。創(chuàng)建第一個(gè) Intel TBB 任務(wù)#include tbb/tbb.h#include using namespace tbb;using namespace std;class first_task : public task public: task* execute( ) cout Hello World!n; return NULL; ;i
14、nt 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);Simple Example: Fibonacci NumbersThis is the serial code:long SerialFib( long n ) if( n2 ) return n; else return SerialFib(n-1)+Seria
15、lFib(n-2);The top-level code for the parallel task-based version is:long ParallelFib( long n ) long sum; FibTask& a = *new(task:allocate_root() FibTask(n,&sum); task:spawn_root_and_wait(a); return sum;The real work is inside struct FibTask. Its definition is shown below.class FibTask: public
16、 task public: const long n; long* const sum; FibTask( long n_, long* sum_ ) : n(n_), sum(sum_) task* execute() / Overrides virtual function task:execute if( nCutOff ) *sum = SerialFib(n); else long x, y; FibTask& a = *new( allocate_child() ) FibTask(n-1,&x); FibTask& b = *new( allocate_c
17、hild() ) FibTask(n-2,&y); / Set ref_count to two children plus one for the wait. set_ref_count(3); / Start b running. spawn( b ); / Start a running and wait for all children (a and b). spawn_and_wait_for_all(a); / Do the sum *sum = x+y; return NULL; ;END謝謝觀看!Simple Example: Fibonacci NumbersThis
18、 is the serial code:long SerialFib( long n ) if( n2 ) return n; else return SerialFib(n-1)+SerialFib(n-2);The top-level code for the parallel task-based version is:long ParallelFib( long n ) long sum; FibTask& a = *new(task:allocate_root() FibTask(n,&sum); task:spawn_root_and_wait(a); return
19、 sum;ThiscodeusesataskoftypeFibTasktodotherealwork.Itinvolvesthefollowingdistinctsteps:1.Allocatespaceforthetask.Thisisdonebyaspecialoverloadednewandmethodtask:allocate_root.The_rootsuffixinthenamedenotesthefactthatthetaskcreatedhasnoparent.Itistherootofatasktree.Tasksmustbeallocatedbyspecialmethods
20、sothatthespacecanbeefficientlyrecycledwhenthetaskcompletes.2.ConstructthetaskwiththeconstructorFibTask(n,&sum)invokedbynew.Whenthetaskisruninstep3,itcomputesthenthFibonaccinumberandstoresitinto*sum.3.Runthetasktocompletionwithtask:spawn_root_and_wait.The real work is inside struct FibTask. Its d
21、efinition is shown below.class FibTask: public task public: const long n; long* const sum; FibTask( long n_, long* sum_ ) : n(n_), sum(sum_) task* execute() / Overrides virtual function task:execute if( nCutOff ) *sum = SerialFib(n); else long x, y; FibTask& a = *new( allocate_child() ) FibTask(
22、n-1,&x); FibTask& b = *new( allocate_child() ) FibTask(n-2,&y); / Set ref_count to two children plus one for the wait. set_ref_count(3); / Start b running. spawn( b ); / Start a running and wait for all children (a and b). spawn_and_wait_for_all(a); / Do the sum *sum = x+y; return NULL;
23、;MethodFibTask:execute()doesthefollowing:Checksifnissosmallthatserialexecutionwouldbefaster.FindingtherightvalueofCutOffrequiressomeexperimentation.Avalueofatleast16workswellinpracticeforgettingmostofthepossiblespeedupoutofthisexample.Resortingtoasequentialalgorithmwhentheproblemsizebecomessmallisch
24、aracteristicofmostdivide-and-conquerpatternsforparallelism.Findingthepointatwhichtoswitchrequiresexperimentation,sobesuretowriteyourcodeinawaythatallowsyoutoexperiment.Iftheelseistaken,thecodecreatesandrunstwochildtasksthatcomputethe(n-1)thand(n-2)thFibonaccinumbers.Here,inheritedmethodallocate_chil
25、d()isusedtoallocatespaceforthetask.Rememberthatthetop-levelroutineParallelFibusedallocate_root()toallocatespaceforatask.Thedifferenceisthatherethetaskiscreatingchildtasks.Thisrelationshipisindicatedbythechoiceofallocationmethod.Callsset_ref_count(3).Thenumber3representsthetwochildrenandanadditionali
26、mplicitreferencethatisrequiredbymethodspawn_and_wait_for_all.Makesuretocallset_reference_count(3)beforespawninganychildren.Failuretodosoresultsinundefinedbehavior.Thedebugversionofthelibraryusuallydetectsandreportsthistypeoferror.Spawnstwochildtasks.Spawningataskindicatestotheschedulerthatitcanrunth
27、etaskwheneveritchooses,possiblyinparallelwithothertasks.Thefirstspawning,bymethodspawn,returnsimmediatelywithoutwaitingforthechildtasktostartexecuting.Thesecondspawning,bymethodspawn_and_wait_for_all,causestheparenttowaituntilallcurrentlyallocatedchildtasksarefinished.Afterthetwochildtaskscomplete,t
28、heparentcomputesx+yandstoresitin*sum.https:/ TBB 和 OpenMP API 通過(guò)工作竊取來(lái)管理任務(wù)調(diào)度。在工作竊取過(guò)程中,線程池中的每個(gè)線程維護(hù)一個(gè)雙端列隊(duì)本地任務(wù)池。一個(gè)線程像使用堆棧一樣使用自身的任務(wù)池,并將所產(chǎn)生的新任務(wù)推堆棧頂部。當(dāng)一個(gè)線程執(zhí)行了一個(gè)任務(wù), 它會(huì)首先從本地堆棧的頂部彈出一個(gè)任務(wù)。堆棧頂部的任務(wù)是最新的,因此最有可能訪問(wèn)到數(shù)據(jù)緩存中的熱點(diǎn)數(shù)據(jù)。如果本地任務(wù)池中沒(méi)有任務(wù),它會(huì)試圖從另一線程()那里竊取工作。當(dāng)工作被竊取時(shí),一個(gè)線程會(huì)將偷竊對(duì)象的雙端隊(duì)列作為普通隊(duì)列來(lái)使用,因,所竊取的僅是偷竊對(duì)象雙端隊(duì)列中最舊的任務(wù)。對(duì)于遞歸算
29、法,這些最舊的任務(wù)均為位于任務(wù)樹高處的節(jié)點(diǎn),因此屬于大型工作塊,并且通常不是偷竊對(duì)象數(shù)據(jù)緩存中的熱點(diǎn)。因此,工作竊取是一個(gè)實(shí)現(xiàn)負(fù)載平衡并且維持本地化緩存的高效機(jī)制。To set up the terminology for the following discussion, a thread belonging to TBBs internal thread pool will be called a “worker”, and any other thread will go under the alias of “master” (e.g. applications main thread
30、, or any thread explicitly created by programmer).When the first master initialized TBB 2.2 task scheduler, the following things happened:1) Global “arena” object was instantiated2) Internal pool of “worker” threads (or simply workers) was created3) Workers registered themselves in the arenaWhen the master
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 保險(xiǎn)業(yè)務(wù)居間合同書
- 合作經(jīng)營(yíng)公路運(yùn)輸合同
- 培訓(xùn)協(xié)議約定合同
- 勞保協(xié)議合同
- 明星代言合同協(xié)議
- 伐木工協(xié)議合同
- 鋪裝合同協(xié)議
- 回遷房二手房合同協(xié)議書
- 項(xiàng)目資金合同協(xié)議
- 污水池施工合同協(xié)議書
- 環(huán)境有害物質(zhì)管理辦法
- 《中國(guó)特色社會(huì)主義進(jìn)入新時(shí)代》PPT課件下載
- 基于PLC的溫室大棚控制系統(tǒng)設(shè)計(jì)
- 證券投資基金信息披露xbrl模板第3號(hào)《年度報(bào)告和半年度報(bào)告》
- 工程力學(xué)電子教材
- 70周歲以上老年人三力測(cè)試題庫(kù)換領(lǐng)永久駕駛證
- 動(dòng)物免疫學(xué)第五章細(xì)胞因子
- 新版防雷檢測(cè)職業(yè)技能競(jìng)賽綜合知識(shí)試題庫(kù)(精簡(jiǎn)500題)
- 2023年新華人壽保險(xiǎn)股份有限公司招聘筆試題庫(kù)及答案解析
- GB/T 4513.1-2015不定形耐火材料第1部分:介紹和分類
- GB/T 3452.1-2005液壓氣動(dòng)用O形橡膠密封圈第1部分:尺寸系列及公差
評(píng)論
0/150
提交評(píng)論