亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

.NET4.0并行計(jì)算技術(shù)基礎(chǔ)(4)

系統(tǒng) 1816 0
.NET4.0并行計(jì)算技術(shù)基礎(chǔ)(4)
這是一個(gè)系列講座,前面幾講的鏈接為:
版權(quán)聲明在第一講中。
================================================

19.3 讓一切“并行”——任務(wù)并行庫(kù)原理及應(yīng)用

19.3.1 任務(wù)并行庫(kù)簡(jiǎn)介

任務(wù)并行庫(kù)( TPL Task Parallel Library )是 .NET 4.0 為幫助軟件工程師開發(fā)并行程序而提供的一組類,位于 System.Threading System.Threading.Tasks 這兩個(gè)命名空間中,駐留在 3 個(gè) .NET 核心程序集 mscorlib.dll System.dll System.Core.dll 里。使用這些類,可以讓軟件工程師在開發(fā)并行程序時(shí),將精力更關(guān)注于問題本身,而不是諸如線程的創(chuàng)建、取消和同步等繁瑣的技術(shù)細(xì)節(jié)。

使用 TPL 開發(fā)并行程序,考慮的著眼點(diǎn)是“任務(wù) (task) ”而非“線程”。

一個(gè)任務(wù)是一個(gè) Task 類的實(shí)例,它代表某個(gè)需要計(jì)算機(jī)執(zhí)行的數(shù)據(jù)處理工作,其特殊之處在于:

TPL 中,任務(wù)通常代表一個(gè)可以被計(jì)算機(jī) 并行執(zhí)行 的工作。

任務(wù)可以由任何一個(gè)線程執(zhí)行,特定的任務(wù)與特定的線程之間沒有綁定關(guān)系。在目前的版本中, TPL 使用 .NET 線程池中的線程來(lái)執(zhí)行任務(wù)。

負(fù)責(zé)將任務(wù)“分派”到線程的工作則“任務(wù)調(diào)度器( Task Scheduler )”負(fù)責(zé)。任務(wù)調(diào)度器集成于線程池中。

我們?cè)谇懊娼榻B并行計(jì)算基本原理時(shí),曾經(jīng)介紹過 OpenMP ,通過在 Fortran C/C++ 代碼中添加特定的編譯標(biāo)記,實(shí)現(xiàn)了 OpenMP 標(biāo)準(zhǔn)的編譯器會(huì)自動(dòng)地生成相應(yīng)的并行代碼。然而, TPL 采用了另一種實(shí)現(xiàn)方式,它自行是作為 .NET 平臺(tái)的一個(gè)有機(jī)組成部分而出現(xiàn)的,并不對(duì)編譯器提出特殊要求,當(dāng)應(yīng)用程序使用 TPL 編寫并行程序時(shí),所有代碼會(huì)被直接編譯為 IL 指令,然后由 CLR 負(fù)責(zé)執(zhí)行之,整個(gè)過程完全等同于標(biāo)準(zhǔn)的 .NET 應(yīng)用程序。換言之,對(duì)于應(yīng)用軟件開發(fā)工程師而言,使用 TPL 開發(fā)并行程序,在編程方式上沒有任何變化,只不過是編程時(shí)多了幾個(gè)類可用,并且處理數(shù)據(jù)時(shí)需要使用并行算法。

提示:

之所以微軟在設(shè)計(jì) .NET 4.0 并行擴(kuò)展的時(shí)候放棄了類似于 OpenMP 的方式,是因?yàn)? .NET 平臺(tái)本身是跨語(yǔ)言的,如果象 OpenMP 那樣,就不得不對(duì)所有的 .NET 編程語(yǔ)言設(shè)定特定的編譯指令,并且需要修改現(xiàn)有的各種語(yǔ)言編譯器,這無(wú)疑是不明智的一個(gè)決定。

另外,針對(duì)并行程序中令人頭痛的異常處理問題, TPL 提供了一個(gè)增強(qiáng)了的 .NET 異常處理機(jī)制,并且在 Visual Studio 中集成了相應(yīng)的調(diào)試工具。

擴(kuò)充閱讀:

使用 Visual Studio 2010 調(diào)試并行程序

Visual Studio 2010 對(duì)并行程序的調(diào)試提供了強(qiáng)大的手段,給程序設(shè)計(jì)好斷點(diǎn)以后,可以使用 Threads 窗口查看當(dāng)前程序的所有線程:

.NET4.0并行計(jì)算技術(shù)基礎(chǔ)(4)

19 ? 9 中雙擊某行,可以讓指定的線程成為當(dāng)前“激活”的“被調(diào)試”的線程。

另外, Parallel Tasks 窗口展示了當(dāng)前程序所運(yùn)行的所有任務(wù):

.NET4.0并行計(jì)算技術(shù)基礎(chǔ)(4)

Parallel Stacks 窗口中,則可以直觀地看到每個(gè)線程的調(diào)用堆棧:

.NET4.0并行計(jì)算技術(shù)基礎(chǔ)(4)

有關(guān) Visual Studio 2010 調(diào)試器的使用方法,請(qǐng)查詢 MSDN 。本書不再贅述。

19.3.2 從線程到任務(wù)

在對(duì) TPL 有了基本的了解之后,我們以一個(gè)實(shí)例來(lái)介紹如何使用 TPL 開發(fā)并行程序( 19 ? 12 )。

.NET4.0并行計(jì)算技術(shù)基礎(chǔ)(4)

1 示例簡(jiǎn)介

示例項(xiàng)目 CalculateVarianceOfPopulation 完成以下任務(wù):

測(cè)試一批數(shù)據(jù)的總體方差。

依據(jù)數(shù)理統(tǒng)計(jì)理論,可以使用以下公式計(jì)算方差:

很明顯,要完成計(jì)算數(shù)據(jù)總體方差的任務(wù),必須完成以下的工作:

1 )計(jì)算出所有數(shù)據(jù)的平均值,這很簡(jiǎn)單,直接求數(shù)據(jù)的和然后除以數(shù)據(jù)個(gè)數(shù)就行了。

2 )計(jì)算所有數(shù)與平均值的差值的平方,然后求和

3 )將第( 2 )步求出的各除以數(shù)據(jù)個(gè)數(shù),得到總體方差。

分析一下,在上述 3 個(gè)子任務(wù)中,第( 2 )步是最有可能并行執(zhí)行的。我們可以將整個(gè)數(shù)據(jù)分成幾組,然后對(duì)每組數(shù)據(jù)并行執(zhí)行處理任務(wù)。

下面簡(jiǎn)要介紹一下示例程序的技術(shù)要點(diǎn),完整代碼可以在配套光盤上找到。

2 直接使用線程實(shí)現(xiàn)并行處理

在示例程序中,測(cè)試數(shù)據(jù)是隨機(jī)生成的,放在一個(gè) double 類型的數(shù)組中,其大小由常量 DataSize 確定。

示例程序是一個(gè) windows 應(yīng)用程序,為了保證程序可以及時(shí)地響應(yīng)用戶操作,均采用多線程方式在后臺(tái)執(zhí)行計(jì)算任務(wù),為此設(shè)計(jì)了一個(gè)跨線程安全顯示信息的函數(shù):

private void ShowInfo(string Info)

{

if ( InvokeRequired )

{

Action<string> del = (str) => { rtfInfo.AppendText(str); };

this.BeginInvoke(del, Info);

}

else

rtfInfo.AppendText(Info);

}

注意上面用到了 Control.InvokeRequired 屬性用于判斷是否跨線程訪問 RichTextBox 控件。

串行程序沒什么好說(shuō)的,示例程序?qū)⑵浞庋b為一個(gè) CalculateVarianceInSequence() 函數(shù),直接調(diào)用就行了。

有趣的是如何使用線程來(lái)并行處理。常量 ThreadCount 用于定義并行執(zhí)行上述第( 2 )個(gè)任務(wù)的線程數(shù),示例中將其設(shè)置為 4 ,因此,在程序運(yùn)行時(shí),有 4 個(gè)線程同時(shí)計(jì)算“每個(gè)數(shù)據(jù)與總體平均值的差值的平方和”。這是一個(gè)典型的線程同步問題。

我們使用一個(gè)窗體的成員變量 SquareSumUsedByThread 保存計(jì)算結(jié)果,由于有 4 個(gè)線程要訪問它,因此必須給其加上一把鎖。這里有一個(gè)需要注意的地方,為了提升程序性能,這把“鎖”鎖定的對(duì)象不能是主窗體對(duì)象,更不能是主窗體類型,而是一個(gè)專用于互斥的對(duì)象。為此,在主窗體中我添加了以下變量:

private object SquareSumLockObject = new object();

而在線程函數(shù)中這樣訪問它:

//…

lock (SquareSumLockObject)

{

SquareSumUsedByThread += sum;

}

//…

這是一個(gè)很重要的多線程開發(fā)技巧,讀者需要注意。

另外,工作線程在執(zhí)行計(jì)算任務(wù)時(shí)需要知道一些信息:

l 它負(fù)責(zé)處理整個(gè)數(shù)組中“哪塊”區(qū)域?這可以通過它要處理的數(shù)據(jù)的起始索引和要處理的數(shù)據(jù)個(gè)數(shù)確定。

l 總體數(shù)據(jù)的平均值,這個(gè)值在算法前一步使用串行算法計(jì)算得到的。

讀者一看到這,應(yīng)該馬上意識(shí)到這是一個(gè)典型的“將數(shù)據(jù)從外界傳送到線程中”問題,可以使用本書第 16 章介紹過的相關(guān)編程技巧來(lái)解決。在本示例中,定義了一個(gè) ThreadArgu 輔助類用于封裝這些信息。由此得到線程函數(shù)的代碼框架:

private void CalculateSquareSumInParallelWithThread( object ThreadArguObject )

{

ThreadArgu argu = ThreadArguObject as ThreadArgu ;

// ……(代碼略)

}

另外,由于有 4 個(gè)工作線程執(zhí)行計(jì)算任務(wù),因此,我們可以使用第 17 章介紹過的 CountdownEvent 對(duì)象來(lái)等待這 4 個(gè)線程的工作結(jié)束。

如果讀者掌握了前幾章的內(nèi)容,那么在上面介紹的基礎(chǔ)之上,您完全可以不看示例代碼自行編出這個(gè)程序,這是一個(gè)很好的編程練習(xí)。

====================================

下一講 《.NET4.0并行計(jì)算基礎(chǔ)(5)》

.NET4.0并行計(jì)算技術(shù)基礎(chǔ)(4)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日韩免费一区二区 | 国产精品线在线精品国语 | aⅴ在线免费观看 | 日本一区视频在线 | 毛片免费观看网址 | 毛片在线网址 | 色婷婷激婷婷深爱五月小蛇 | 99九九视频| 欧美精品v欧洲精品 | 久久精品国产91久久麻豆自制 | 猫咪视频成人永久免费观看 | 亚洲国产精品综合福利专区 | 欧美国产成人一区二区三区 | 中文字幕在线一区二区三区 | 国产免费播放一区二区三区 | 欧美亚洲综合另类型色妞 | 欧美18videosex灌满| 中国一级特黄真人毛片免 | 亚洲人成网站999久久久综合 | 四虎影城 | 99视频在线观看视频一区 | 日本级毛片免费观看 | 99视频这里有精品 | 亚洲国产激情一区二区三区 | 国产亚洲精品一品区99热 | 亚洲精品视频免费在线观看 | 精品亚洲成a人7777在线观看 | www.青草视频| 欧美激情观看一区二区久久 | 99尹人香蕉国产免费天天拍 | 伊人精品在线视频 | 寂寞午夜影院 | 999毛片免费观看 | 国产高清在线91福利 | 国产亚洲精品一区二区久久 | 日本在线亚州精品视频在线 | 午夜性爽视频男人的天堂在线 | 男人午夜免费视频 | 国产精品美女久久久久久 | 涩涩一区| 国产成人免费在线视频 |