




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、TBB的幾個特性與線程不同,您可以對任務使用更高程度的抽象。Intel 聲稱,在 Linux 系統上,啟動和結束任務的速度是對線程執行相同操作的 18 倍。Intel TBB 附帶了一個任務調度程序,該程序可以跨多個邏輯和物理內核高效地處理負載平衡。Intel TBB 中的默認任務調度策略不同于大多數線程調度程序所擁有的輪詢策略。Intel TBB 提供了一些可直接使用的線程安全容器,比如 concurrent_vector 和 concurrent_queue。可以使用通用的并行算法,如 parallel_for 和 parallel_reduce。模板類 atomic 中提供了無鎖(Loc
2、k-free,也稱為 mutex-free)并發編程支持。這種支持使得 Intel TBB 適合用于高性能的應用程序,因為 Intel TBB 可以鎖定和解除鎖定互斥體 (mutex)。這都是用 C+ 實現的!沒有進行任何擴展或使用宏,Intel TBB 只使用這種語言,同時還使用了大量的模板。上圖的內容可以分為以下幾類:l 通用并行算法TBB提供了parallel_for,parallel_while,parallel_reduce等算法,應用于不同的并行算法場景l 并發容器這是對常見容器的線程安全版本的實現,同時考慮到性能要求,提供了細粒度的鎖機制,TBB2.0里提供的容器包括hash m
3、ap,vector,queue。l 任務調度器:提供了task機制的封裝l 同步原語:提供了原子操作、mutex、lock等同步原語的封裝l 內存分配:提供了對cache機制更友好的支持parallel_forl 摘要parallel_for是在一個值域執行并行迭代操作的模板函數。l 語法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)表示一個循環的并行執行: 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原型語義Body:Body(const Body&) 拷貝構造Body:Body()析構void Body:operator()(Range& range) const對range對象應用body對象l描述parallel_for(range, body, partitioner)提
6、供了并行迭代的泛型形式。它表示在區域的每個值,并行執行body。partitioner選項指定了分割策略。Range類型必須符合Range概念模型。body必須符合下表的要求:采用最后一個模板以及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& )構造函數R:R()析構函數bool R:empty() const區域為空返回turebool R:is_divisible() const 如果區域可再分,返回tureR:R(R& r
8、, split)將r分為兩個子區域Parallel_reducel 摘要parallel_reduce模板在一個區域迭代,將由各個任務計算得到的部分結果合并,得到最終結果。parallel_reduce對區域(range)類型的要求與parallel_for一樣。l 語法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()的左標識元素Value Func:operator()(const Range& range, const Value& x)累計從初始值x開始的子區域的結果Valu
10、e Reduction:operator()(const Value& x, const Value& y);合并x跟y的結果l 描述parallel_reduce模板有兩種形式。函數形式是為方便與lambda表達式一起使用而設計。第二種形式是為了最小化數據拷貝。 下面的表格總結了第一種形式中的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任務Intel TBB 基于 任務 的概念。您需要定義自己的任務,這些任務是從 tbb:task 中派生的,并使用 tbb/task.h 進行聲明。用戶需要在自己的代碼中重寫純虛擬方法 task* task:execute ( )。下面展示了每個 Intel TBB 任務的一些屬性:當 Intel TBB 任務調度程序選擇運行一些任務時,會調用該任務的 execute 方法。這是入口點。execute 方法會返回一個 task*,告訴調度程序將要運行的下一個任務。如果它返回 NULL,那么調度程序可以自由選擇下一個任務。task:task( ) 是虛擬的,不
13、管用戶任務占用了什么資源,都必須在這個析構函數 (destructor) 中釋放。任務是通過調用 task:allocate_root( ) 來分配的。主任務通過調用 task:spawn_root_and_wait(task) 來完成任務的運行。創建第一個 Intel TBB 任務#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 通過工作竊取來管理任務調度。在工作竊取過程中,線程池中的每個線程維護一個雙端列隊本地任務池。一個線程像使用堆棧一樣使用自身的任務池,并將所產生的新任務推堆棧頂部。當一個線程執行了一個任務, 它會首先從本地堆棧的頂部彈出一個任務。堆棧頂部的任務是最新的,因此最有可能訪問到數據緩存中的熱點數據。如果本地任務池中沒有任務,它會試圖從另一線程()那里竊取工作。當工作被竊取時,一個線程會將偷竊對象的雙端隊列作為普通隊列來使用,因,所竊取的僅是偷竊對象雙端隊列中最舊的任務。對于遞歸算
29、法,這些最舊的任務均為位于任務樹高處的節點,因此屬于大型工作塊,并且通常不是偷竊對象數據緩存中的熱點。因此,工作竊取是一個實現負載平衡并且維持本地化緩存的高效機制。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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 智慧城市中的智能醫療服務創新
- 機電工程考試數據分析技術試題及答案
- 2025年光通訊用石英玻璃材料合作協議書
- 公共部門創新與政策落地機制研究試題及答案
- 2025年醫療健康數據隱私保護技術在醫療數據共享平臺中的合規應用報告
- 西方政治制度下的公共衛生治理試題及答案
- 無人機配送技術在物流行業物流行業市場拓展中的應用與機遇報告
- 政府透明度與公共政策效果試題及答案
- 把握網絡工程師考試方向與2025年試題與答案指引
- 高效的網絡管理方法與試題及答案
- 玉盤二部合唱簡譜
- 保護眼睛家長進課堂
- 質量控制計劃(CP)
- 關稅系統崗位練兵業務知識測試題庫(綜合知識)附答案
- GB/T 7476-1987水質鈣的測定EDTA滴定法
- 新生兒早期基本保健(EENC)指南要點解讀課件
- 繩索救援技術(課堂)課件
- 英語初級聽力(Listen-to-This-1)教師用書1
- 商混站(商品混凝土公司)安全生產操作規程
- 三年級下冊英語課件- Module 4 Unit 1 We'll pick fruit. 外研社(一起)(共15張PPT)
- 版高考語文標準作文紙
評論
0/150
提交評論