三分钟总览微软任务并行库TPL
點(diǎn)擊上方藍(lán)字進(jìn)行關(guān)注
有小伙伴問(wèn)我每天忽悠的TPL是什么?
?? 這次站位高一點(diǎn),嚴(yán)肅講一講。
引言
俗話(huà)說(shuō),不想開(kāi)飛機(jī)的程序員不是一名好爸爸;作為微軟技術(shù)棧的老鳥(niǎo),一直將代碼整潔之道奉為經(jīng)典, 優(yōu)秀的程序員將優(yōu)雅、高性能的代碼看成自己的臉面。
今天探討下我對(duì).NET并行編程庫(kù)Task Parallel Library的理解,開(kāi)足馬力,準(zhǔn)備壓榨CPU了。
雙核cpu的真相.gif技術(shù)背景
硬件線(xiàn)程和軟件線(xiàn)程
? ?多核處理器帶有一個(gè)以上的物理內(nèi)核:物理內(nèi)核是真正的獨(dú)立處理單元,多個(gè)物理內(nèi)核使得多條指令能夠同時(shí)并行運(yùn)行。
硬件線(xiàn)程也稱(chēng)為邏輯內(nèi)核,一個(gè)物理內(nèi)核可能會(huì)使用超線(xiàn)程技術(shù)提供多個(gè)硬件線(xiàn)程,所以一個(gè)硬件線(xiàn)程并不代表一個(gè)物理內(nèi)核。程序通過(guò)Environment.ProcessorCount?得到的就是邏輯內(nèi)核(本人的機(jī)器是i5-5300U 虛擬4核), Windows中每個(gè)運(yùn)行的程序都是一個(gè)進(jìn)程,每一個(gè)進(jìn)程都會(huì)創(chuàng)建并運(yùn)行一個(gè)或多個(gè)線(xiàn)程,這些線(xiàn)程稱(chēng)為軟件線(xiàn)程,硬件線(xiàn)程就像是一條泳道,而軟件線(xiàn)程就是在其中游泳的人。
并行場(chǎng)景
.NET引入的Task Parallel Library(任務(wù)并行庫(kù),TPL),動(dòng)態(tài)地?cái)U(kuò)展并發(fā)度,以最有效的方式使用所有可用的處理器。
另外TPL支持分區(qū)工作、支持基于ThreadPool調(diào)度、支持取消異步操作、支持狀態(tài)管理。
通過(guò)TPL專(zhuān)注與讓程序完成你業(yè)務(wù)意義上的任務(wù),同時(shí)最大限度的提高程序性能。
TPL同時(shí)支持?jǐn)?shù)據(jù)并行、任務(wù)并行和流水線(xiàn)Dataflow
1.數(shù)據(jù)并行:有大量數(shù)據(jù)需要處理,并且必須對(duì)每一份數(shù)據(jù)執(zhí)行同樣的操作;2.任務(wù)并行:通過(guò)任務(wù)并發(fā)運(yùn)行不同的操作;3.流水線(xiàn):任務(wù)并行和數(shù)據(jù)并行的結(jié)合體(需要引入System.Threading.Tasks.Dataflow組件庫(kù))?
其中1、3 已經(jīng)在上文演示,本文就隨手拿數(shù)據(jù)并行、任務(wù)并行聊一聊。
編程實(shí)踐
1. 數(shù)據(jù)并行
找到100000以?xún)?nèi)素?cái)?shù)的個(gè)數(shù)
上文[共享內(nèi)存并發(fā)模型],代碼可做如下優(yōu)化:
由每個(gè)線(xiàn)程獨(dú)立計(jì)算線(xiàn)程內(nèi)迭代產(chǎn)生的素?cái)?shù)和,最后再對(duì)幾個(gè)和求和。
using?System; using?System.Threading.Tasks; using?System.Collections; using?System.Collections.Generic; using?System.Threading; using?System.Diagnostics;///?<summary> ///?利用并行編程庫(kù)Parallel,計(jì)算100000內(nèi)素?cái)?shù)的個(gè)數(shù) ///?</summary> namespace?Paralleler {class?Program{static?void?Main(string[]?args){Stopwatch?sw?=?new?Stopwatch();sw.Start();ShareMemory();sw.Stop();Console.WriteLine($"優(yōu)化后的共享內(nèi)存并發(fā)模型耗時(shí):{sw.Elapsed}");}static?void?ShareMemory(){var?sum?=?0;Parallel.For(1,?100000?+?1,?()?=>?0,?(x,?state,?local)?=>{var?f?=?true;if?(x?==?1)f?=?false;for?(int?i?=?2;?i?<=?x?/?2;?i++){if?(x?%?i?==?0)??//?被[2,x/2]任一數(shù)字整除,就不是質(zhì)數(shù)f?=?false;}if?(f?==?true)local++;return?local;},local?=>{Interlocked.Add(ref?sum,?local);});Console.WriteLine($"1-100000內(nèi)質(zhì)數(shù)的個(gè)數(shù)是{sum}");}} } 參數(shù)1,2 表示數(shù)據(jù)并行要操作的對(duì)象; 參數(shù)3localInit表示某線(xiàn)程內(nèi)迭代的初始值,將會(huì)作為參數(shù)4body委托的第3個(gè)參數(shù),只在線(xiàn)程第一次使用;參數(shù)4body表示每個(gè)迭代都需要經(jīng)歷的執(zhí)行體, 這里以線(xiàn)程為單元處理迭代; 參數(shù)5localFinally對(duì)每個(gè)線(xiàn)程的輸出再做一次計(jì)算,入?yún)⑹菂?shù)4的輸出。2. 任務(wù)并行
? 讓許多方法并行運(yùn)行的最簡(jiǎn)單的方法就是使用Parallel類(lèi)的Invoke方法,Invoke方法接受一個(gè)Action的參數(shù)組
void System.Threading.Tasks.Parallel.Invoke(WatchMovie, HaveDinner, ReadBook, WriteBlog);這段代碼會(huì)創(chuàng)建指向每一個(gè)方法的委托。
沒(méi)有特定的執(zhí)行順序
Parallel.Invoke方法只有在4個(gè)方法全部完成之后才會(huì)返回。它至少需要4個(gè)硬件線(xiàn)程才足以讓這4個(gè)方法并發(fā)運(yùn)行。
但并不保證這4個(gè)方法能夠同時(shí)啟動(dòng)運(yùn)行,如果一個(gè)或者多個(gè)內(nèi)核處于繁忙狀態(tài),那么底層的調(diào)度邏輯可能會(huì)延遲某些方法的初始化執(zhí)行。
捕捉并行循環(huán)中發(fā)生的異常
當(dāng)并行迭代中調(diào)用的委托拋出異常,這個(gè)異常沒(méi)有在委托中被捕獲到時(shí),就會(huì)變成一組異常,新的System.AggregateException負(fù)責(zé)處理這一組異常。
本文為微軟TPL入門(mén)級(jí)教程,學(xué)習(xí)一個(gè)專(zhuān)題,了解特性/能力最重要, 剩下的就是結(jié)合場(chǎng)景去應(yīng)用。
本文內(nèi)容和制圖均為原創(chuàng),文章永久更新地址請(qǐng)參閱左下角原文,如對(duì)您有所幫助,【在看、點(diǎn)贊】來(lái)一發(fā),未嘗不可?。
專(zhuān)題相關(guān) 一網(wǎng)打盡
? 三分鐘掌握共享內(nèi)存 & Actor并發(fā)模型~~~
?你管這叫"線(xiàn)程安全"?~~~
?.Net線(xiàn)程同步技術(shù)解讀
?Redis分布式鎖抽絲剝繭
?看過(guò)這么多爆文,依舊走不好異步編程這條路?
?TPL Dataflow組件應(yīng)對(duì)高并發(fā),低延遲要求
?如何利用.NETCore向Azure EventHubs準(zhǔn)實(shí)時(shí)批量發(fā)送數(shù)據(jù)?
?難纏的布隆過(guò)濾器,這次終于通透了
掃碼關(guān)注我們
不會(huì)讓您失望的。
總結(jié)
以上是生活随笔為你收集整理的三分钟总览微软任务并行库TPL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一个简单的方式搞定密码的加盐哈希与验证
- 下一篇: 技术 Leader 怎样带跨一个团队?