| -- |
理解並發編程中的幾種並發方式
時刻謹記並發設計
當你設計代碼利用多核優勢的時候,重要的是不要老是想着C#程序代碼是獨自執行的。C#為並發代碼做了設計,也就是很多代碼可以在同一個進程里同時執行或者交錯執行。相同的類方法可以在並行代碼里執行。如果這個方法在靜態變量里保存了狀態,以后再使用這個狀態,這樣的並行執行會產生非期望的和不可預料的結果。
就像前邊解釋的,多核微處理器上的並行編程使用的是共享內存模型。如果沒有考慮並發,那些在相同的共享內存里的數據可能會導致不可預料的結果。
使每個類和方法可以沒有副作用的並行執行是一個好的實踐。如果你考慮不能講某些類、方法、組件不能設計成並發的,在設計並行代碼前需要對設計進行測試。
設計過程中探測到的每個子問題都應該有能力在其他子問題執行的時候並行執行。當你認為有必要限制某個使用遺留類、方法、組件的子問題的並發代碼的時候,你需要在設計文檔里記載清楚。一旦開始使用並發代碼工作,極易發生不能與已存的類、方法、組件協作,因為他們沒有做並發執行的設計。
理解交錯並發、並發和並行的不同
當有兩個軟件線程都執行四個指令時,圖1-15展示了交錯並行和並行的不同。交錯並發執行的場景交錯的執行每個線程上的指令,但是並發執行的場景同時執行兩條指令。代碼設計必須同時考慮到這兩種場景。
並行(Parallelized)代碼可以在很多的不同的並發和交錯並發的場景中執行,甚至是在相同的硬件配置中執行。所以,並行設計的一個很大的挑戰就是確保其執行順序的有效性和結果的正確性,否則就會長生不正確的結果。如果你需要以一種特殊的順序或者代碼的某些部分不能夠同時執行,那么就有必要確保這些部分代碼不能並行執行。你不能假設他們不能並發執行,因為你執行它很多次,它會產生希望的結果。當你為並發和並行而設計是,你必須確保你的思考的正確性。
在下一章中,你將會通過不同種類的代碼示例,學到更多有關並行和並發的不同點。


圖 1-15
並行的任務
Visual C# 2010和.NET 4.0使我們將基於任務的設計轉變成並行的代碼變得容易。然而,為了完成預期的目的,理解並行代碼需要的特殊的測試和協調的步驟是很重要的。你將通過本書余下的部分學習相關的知識。
當你並行化任務的時候,由其導致的首要的沖擊可能就是需要測試不同的選擇。就像前邊解釋的一樣,現在的多核微處理器是異常的復雜,有必要測試不同並行技術的結果直到你可以做出選擇。事實上,順序代碼執行結果相同,但是就像你已經知道的foreach比for循環慢,但是並行執行的時候會不同。當並行化任務的時候,一個並行版本的for循環會根據不同的參數決定並行執行任務的方式,從而提供了不同的性能結果。一旦你經歷了這些場景,當你編寫代碼解決類似問題或者進行類似的任務設計的時候,就會考慮到這些情況。
有必要連接多個任務,代碼被分解成多個任務,並行執行操作,收集結果,然后像這樣往復循環。在決定並行執行對某個問題不是好的選擇之前,盡量創建一個好像有1000個內核並行執行的圖表。如果一個算法的某些並行執行部分沒有提供期望的伸縮性,你還有機會與其他任務並行的執行它。
