並行程式設計之PLINQ

2021-09-06 01:56:30 字數 3386 閱讀 5429

並行

linq (plinq)

是linq

模式的並行實現。

plinq

的主要用途是通過在多核計算機上以並行方式執行查詢委託來加快

linq to objects

查詢的執行速度。

與順序linq

查詢一樣,

plinq

查詢對任何記憶體中

ienumerable

或ienumerable<(of <(t>)>)

資料來源進行操作,並推遲執行,這意味著在列舉查詢之前不會開始執行這些操作。主要區別是

plinq

嘗試充分利用系統中的所有處理器。它利用所有處理器的方法是,將資料來源分成片段,然後在多個處理器上對單獨工作執行緒上的每個片段並行執行查詢。在許多情況下,並行執行意味著查詢執行速度顯著提高。

通過並行執行,

plinq

通常只需向資料來源新增

asparallel

查詢操作,即可在某些查詢型別的舊版**上獲得顯著的效能改進。但是,並行可能引入其自己的複雜性,因此並非所有查詢操作在

plinq

中都執行得更快。

事實上,並行降低了某些查詢的速度

。system.linq..::.parallelenumerable

類公開plinq

的幾乎所有功能。此類和

system.linq

命名空間型別的其餘部分一起編譯到

system.core.dll

程式集中。

當您編寫查詢時,通過在資料來源上呼叫

parallelenumerableasparallel()()()

擴充套件方法來選擇使用

plinq

,如下面的示例所示。

var source = enumerable.range(1, 10000);

// opt-in to plinq with asparallel

var evennums = from num in source.asparallel()

where compute(num) > 0

select num;

預設情況下,

plinq

使用主機上的所有處理器,這些處理器的數量最多可達

64 個。通過使用

withdegreeofparallelism()()()

方法,可以指示

plinq

使用不多於指定數量的處理器。這在當您要確保計算機上執行的其他程序收到一定的

cpu

時間量時非常有用。下面的**段將查詢限制為最多使用兩個處理器。

var query = from item in source.asparallel().withdegreeofparallelism(2)

where compute(item) > 42

select item;

為了實現加速,

plinq

查詢必須具有足夠的適合並行工作來彌補開銷。工作可表示為每個委託的計算開銷與源集合中元素數量的乘積。假定某個操作可並行化,則它的計算開銷越高,加速的可能性就越大。例如,如果某個函式執行花費的時間為

1 毫秒,則針對

1000

個元素進行的順序查詢將花費

1 秒來執行該操作,而在四核計算機上進行的並行查詢可能只花費

250

毫秒。這樣就產生了

750

毫秒的加速。如果該函式對於每個元素需要花費

1 秒來執行,則加速將為

750

秒。如果委託的開銷很大,則對於源集合中的很少幾個項,

plinq

可能會提供明顯的加速。相反,包含無關緊要委託的小型源集合通常不適合於

plinq

。在下面的示例中,

querya

可能適合於

plinq

(假定其

select

函式涉及大量工作)。

queryb

可能不適合,原因是

select

語句中沒有足夠的工作,並且並行化的開銷將抵銷大部分或全部加速。

var querya = from num in source.asparallel()

select expensivefunction(num); //good for plinq

var queryb = from num in source.asparallel()

where num % 2 > 0

select num; //not as good for plinq

plinq

將始終嘗試至少按與查詢以順序方式執行同樣的速度來執行查詢。儘管

plinq

不會檢視使用者委託的計算開銷有多高或輸入源有多大,但它卻會查詢某些查詢"形狀

"。具體而言,它將查詢通常會導致查詢在並行模式下執行更慢的查詢運算子或運算子組合。如果找到此類形狀,

plinq

預設情況下會轉而使用順序模式。

但是,在衡量特定查詢的效能後,您可能會確定該查詢在並行模式下實際執行更快。在這些情況下,您可以通過

parallelenumerablewithexecutionmode()()()

方法使用

parallelexecutionmode..::.forceparallelism

標誌,以指示

plinq

對查詢進行並行化。有關更多資訊,請參見

如何:在

plinq

中指定執行模式。

下面的列表介紹了

plinq

預設情況下將按順序模式執行的查詢形狀:

下面的示例演示乙個未排序的並行查詢,該查詢篩選與某個條件匹配的所有元素,而不會嘗試以任何方式對結果進行排序。此查詢不一定會生成源序列中滿足條件的前

1000

個城市,而是會生成滿足條件的某一組

1000

個城市。您可以通過對源序列使用

asordered()()()

運算子來啟用順序保留。然後,您可以稍後通過使用

asunordered()()()

方法在查詢中禁用順序保留。

var cityquery = (from city in cities.asparallel()

where city.population > 10000

select city)

.take(1000);

查詢運算子和排序

下面的查詢運算子將順序保留引入查詢的所有後續運算中,或直至呼叫

asunordered()()()

為止:下面的

plinq

查詢運算子在某些情況下可能要求經過排序的源序列生成正確的結果:

C 並行程式設計 PLINQ

實列 console.writeline hello world console.writeline 當前計算機處理器數 environment.processorcount concurrentqueueproducts new concurrentqueue 向集合中新增多條資料 可以修改資料量...

並行程式設計與PLINQ 任務並行

任務並行 在tpl當中還可以使用parallel.invoke方法觸發多個非同步任務,其中 actions 中可以包含多個方法或者委託,paralleloptions用於配置parallel類的操作。public static void invoke action actions public st...

並行處理本地資料PLINQ

簡單介紹 此處介紹的並行處理,主要是處理本地儲存的資料 當使用並行處理時,會把資料拆分為多個小塊,然後用多個執行緒處理這些小塊的資料,多執行緒處理後的資料再統一處理再返回 以下是處理100萬陣列的資料量 如下 using system using system.collections.generic...