日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

.NET4.0并行計算技術基礎(4)

系統 1710 0
.NET4.0并行計算技術基礎(4)
這是一個系列講座,前面幾講的鏈接為:
版權聲明在第一講中。
================================================

19.3 讓一切“并行”——任務并行庫原理及應用

19.3.1 任務并行庫簡介

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

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

一個任務是一個 Task 類的實例,它代表某個需要計算機執行的數據處理工作,其特殊之處在于:

TPL 中,任務通常代表一個可以被計算機 并行執行 的工作。

任務可以由任何一個線程執行,特定的任務與特定的線程之間沒有綁定關系。在目前的版本中, TPL 使用 .NET 線程池中的線程來執行任務。

負責將任務“分派”到線程的工作則“任務調度器( Task Scheduler )”負責。任務調度器集成于線程池中。

我們在前面介紹并行計算基本原理時,曾經介紹過 OpenMP ,通過在 Fortran C/C++ 代碼中添加特定的編譯標記,實現了 OpenMP 標準的編譯器會自動地生成相應的并行代碼。然而, TPL 采用了另一種實現方式,它自行是作為 .NET 平臺的一個有機組成部分而出現的,并不對編譯器提出特殊要求,當應用程序使用 TPL 編寫并行程序時,所有代碼會被直接編譯為 IL 指令,然后由 CLR 負責執行之,整個過程完全等同于標準的 .NET 應用程序。換言之,對于應用軟件開發工程師而言,使用 TPL 開發并行程序,在編程方式上沒有任何變化,只不過是編程時多了幾個類可用,并且處理數據時需要使用并行算法。

提示:

之所以微軟在設計 .NET 4.0 并行擴展的時候放棄了類似于 OpenMP 的方式,是因為 .NET 平臺本身是跨語言的,如果象 OpenMP 那樣,就不得不對所有的 .NET 編程語言設定特定的編譯指令,并且需要修改現有的各種語言編譯器,這無疑是不明智的一個決定。

另外,針對并行程序中令人頭痛的異常處理問題, TPL 提供了一個增強了的 .NET 異常處理機制,并且在 Visual Studio 中集成了相應的調試工具。

擴充閱讀:

使用 Visual Studio 2010 調試并行程序

Visual Studio 2010 對并行程序的調試提供了強大的手段,給程序設計好斷點以后,可以使用 Threads 窗口查看當前程序的所有線程:

.NET4.0并行計算技術基礎(4)

19 ? 9 中雙擊某行,可以讓指定的線程成為當前“激活”的“被調試”的線程。

另外, Parallel Tasks 窗口展示了當前程序所運行的所有任務:

.NET4.0并行計算技術基礎(4)

Parallel Stacks 窗口中,則可以直觀地看到每個線程的調用堆棧:

.NET4.0并行計算技術基礎(4)

有關 Visual Studio 2010 調試器的使用方法,請查詢 MSDN 。本書不再贅述。

19.3.2 從線程到任務

在對 TPL 有了基本的了解之后,我們以一個實例來介紹如何使用 TPL 開發并行程序( 19 ? 12 )。

.NET4.0并行計算技術基礎(4)

1 示例簡介

示例項目 CalculateVarianceOfPopulation 完成以下任務:

測試一批數據的總體方差。

依據數理統計理論,可以使用以下公式計算方差:

很明顯,要完成計算數據總體方差的任務,必須完成以下的工作:

1 )計算出所有數據的平均值,這很簡單,直接求數據的和然后除以數據個數就行了。

2 )計算所有數與平均值的差值的平方,然后求和

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

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

下面簡要介紹一下示例程序的技術要點,完整代碼可以在配套光盤上找到。

2 直接使用線程實現并行處理

在示例程序中,測試數據是隨機生成的,放在一個 double 類型的數組中,其大小由常量 DataSize 確定。

示例程序是一個 windows 應用程序,為了保證程序可以及時地響應用戶操作,均采用多線程方式在后臺執行計算任務,為此設計了一個跨線程安全顯示信息的函數:

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 控件。

串行程序沒什么好說的,示例程序將其封裝為一個 CalculateVarianceInSequence() 函數,直接調用就行了。

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

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

private object SquareSumLockObject = new object();

而在線程函數中這樣訪問它:

//…

lock (SquareSumLockObject)

{

SquareSumUsedByThread += sum;

}

//…

這是一個很重要的多線程開發技巧,讀者需要注意。

另外,工作線程在執行計算任務時需要知道一些信息:

l 它負責處理整個數組中“哪塊”區域?這可以通過它要處理的數據的起始索引和要處理的數據個數確定。

l 總體數據的平均值,這個值在算法前一步使用串行算法計算得到的。

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

private void CalculateSquareSumInParallelWithThread( object ThreadArguObject )

{

ThreadArgu argu = ThreadArguObject as ThreadArgu ;

// ……(代碼略)

}

另外,由于有 4 個工作線程執行計算任務,因此,我們可以使用第 17 章介紹過的 CountdownEvent 對象來等待這 4 個線程的工作結束。

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

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

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

.NET4.0并行計算技術基礎(4)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 汤原县| 木兰县| 集安市| 明水县| 淮南市| 安陆市| 西乌| 法库县| 无极县| 曲沃县| 平谷区| 贡嘎县| 北海市| 齐齐哈尔市| 黑河市| 茶陵县| 西乌珠穆沁旗| 香港 | 平和县| 揭东县| 安吉县| 观塘区| 金湖县| 壤塘县| 密云县| 秦皇岛市| 大丰市| 长治县| 旅游| 广南县| 石柱| 武山县| 乌拉特中旗| 沅陵县| 定陶县| 梁山县| 甘南县| 忻城县| 镇赉县| 堆龙德庆县| 岐山县|