天天看點

8天玩轉并行開發——第一天 Parallel的使用

      随着多核時代的到來,并行開發越來越展示出它的強大威力,像我們這樣的碼農再也不用過多的關注底層線程的實作和手工控制,

要了解并行開發,需要先了解下兩個概念:“硬體線程”和“軟體線程”。

1. 硬體線程

    相信大家手頭的電腦都是雙核以上的,像我這樣古董的電腦都是雙核的,這樣的雙核叫做實體核心。

8天玩轉并行開發——第一天 Parallel的使用

硬體線程又叫做邏輯核心,我們可以在”任務管理器“中檢視”性能“标簽頁,如下圖,我們知道有2個硬體線程。

8天玩轉并行開發——第一天 Parallel的使用

一般情況下,一個實體核心對應一個邏輯核心,比如我這裡的2對2。當然如果你的cpu采用的是超線程技術,那麼可能就會有4個實體核心對應

8個硬體線程,現在有很多伺服器都有8個硬體線程,上午在公司的伺服器上截了個圖。

8天玩轉并行開發——第一天 Parallel的使用

我們要知道并行開發要做的事情就是将任務分攤給這些硬體線程去并行執行來達到負載和加速。

2. 軟體線程

    相信這個大家最熟悉了,我們知道傳統的代碼都是串行的,就一個主線程,當我們為了實作加速而開了很多工作線程,這些工作線程

也就是軟體線程。

好,我們知道了基本概念就ok了,在.net 4.0中,微軟給我們提供了一個新的命名空間:System.Threading.Tasks。這裡面有很多好玩

的東西,作為第一篇就介紹下最基礎,最簡單的Parallel的使用。

8天玩轉并行開發——第一天 Parallel的使用

一: Parallel的使用

在Parallel下面有三個常用的方法invoke,for和forEach。

1:  Parallel.Invoke

    這是最簡單,最簡潔的将串行的代碼并行化。

8天玩轉并行開發——第一天 Parallel的使用

在這個例子中可以擷取二點資訊:

第一:一個任務是可以分解成多個任務,采用分而治之的思想。

第二:盡可能的避免子任務之間的依賴性,因為子任務是并行執行,是以就沒有誰一定在前,誰一定在後的規定了。

2:Parallel.for

 我們知道串行代碼中也有一個for,但是那個for并沒有用到多核,而Paraller.for它會在底層根據硬體線程的運作狀況來充分的使用所有的可

利用的硬體線程,注意這裡的Parallel.for的步行是1。

這裡我們來示範一下,向一個線程安全的集合插入資料,當然這個集合采用原子性來實作線程同步,比那些重量級的鎖機制更加的節省消耗。

8天玩轉并行開發——第一天 Parallel的使用

可以看的出,加速的效果還是比較明顯的。

3:Parallel.forEach

    forEach的獨到之處就是可以将資料進行分區,每一個小區内實作串行計算,分區采用Partitioner.Create實作。

8天玩轉并行開發——第一天 Parallel的使用

這裡還是要說一下:Partitioner.Create(0, 3000000)。

第一:我們要分區的範圍是0-3000000。

第二:我們肯定想知道系統給我們分了幾個區? 很遺憾,這是系統内部協調的,無權告訴我們,當然系統也不反對我們自己指定分區個數,

        這裡可以使用Partitioner.Create的第六個重載,比如這樣:Partitioner.Create(0, 3000000, Environment.ProcessorCount),

        因為 Environment.ProcessorCount能夠擷取到目前的硬體線程數,是以這裡也就開了2個區。

下面分享下并行計算中我們可能有的疑惑?

<1> 如何中途退出并行循環?

      是的,在串行代碼中我們break一下就搞定了,但是并行就不是這麼簡單了,不過沒關系,在并行循環的委托參數中提供了一個

ParallelLoopState,該執行個體提供了Break和Stop方法來幫我們實作。

Break: 當然這個是通知并行計算盡快的退出循環,比如并行計算正在疊代100,那麼break後程式還會疊代所有小于100的。

Stop:這個就不一樣了,比如正在疊代100突然遇到stop,那它啥也不管了,直接退出。

下面舉個例子,當疊代到1000的時候退出循環

8天玩轉并行開發——第一天 Parallel的使用

<2> 并行計算中抛出異常怎麼處理?

 首先任務是并行計算的,處理過程中可能會産生n多的異常,那麼如何來擷取到這些異常呢?普通的Exception并不能擷取到異常,然而為并行誕生的AggregateExcepation就可以擷取到一組異常。

8天玩轉并行開發——第一天 Parallel的使用

<3> 并行計算中我可以留一個硬體線程出來嗎?

  預設的情況下,底層機制會盡可能多的使用硬體線程,然而我們使用手動指定的好處是我們可以在2,4,8個硬體線程的情況下來進行測量加速比。

繼續閱讀