從第一臺計算機問世到現(xiàn)在計算機硬件技術(shù)已經(jīng)有了很大的發(fā)展。不管是現(xiàn)在個人使用的PC還是公司使用的服務器。雙核,四核,八核的CPU已經(jīng)非常常見。這樣我們可以將我們程序分攤到多個計算機CPU中去計算,在過去并行化需要線程的低級操作,難度很大,在.net4.0中的增強了對并行化的支持,使得這一切變得非常簡單 。本次我從以下幾個方面大家講以下.NET 并行
1. 數(shù)據(jù)并行
2. 任務并行
3. 并行Linq
4. 任務工廠
5. 注意事項
本次主要給大家講一下數(shù)據(jù)并行 廢話不說,下面開始了
數(shù)據(jù)并行其實就是指對原集合或者數(shù)組中的數(shù)據(jù)進行劃區(qū)之后分攤到多個CPU或者多個線程執(zhí)行相同的操作 在 .net中的 System.Threading.Tasks 提供了對數(shù)據(jù)并行的支持類 , Parallel.For,Parallel.ForEach和我們經(jīng)常的使用的for 和foreach 十分的相似,你不用創(chuàng)建線程隊列,在基本的循環(huán)中你不用使用鎖。這些.net 會幫你處理,你只需要關(guān)注你自己的業(yè)務 那下面我們就來看看 Parallel.For 和 Parallel.ForEach 是如何使用的
• Parallel.For 簡單使用
復制代碼 代碼如下:
Parallel.For(0, 100, i => {
dosameting()
});
上面的例子是不是和我們經(jīng)常使用的for循環(huán)的影子。 說一下 Parallel.For 的第三個參數(shù)Actionint>類型的委托 不管這個委托的參數(shù)是0個還是多少個他的返回植都是void,那么怎么樣才能獲取到Parallel.For 中的的返回值了,下面的例子將演示如何使用線程本地變量來存儲和檢索由 for 循環(huán)創(chuàng)建的每個單獨任務中的狀態(tài) 通過使用線程本地數(shù)據(jù),您可以避免將大量的訪問同步為共享狀態(tài)的開銷。 在任務的所有迭代完成之前,您將計算和存儲值,而不是寫入每個迭代上的共享資源。 然后,您可以將最終結(jié)果一次性寫入共享資源,或?qū)⑵鋫鬟f到另一個方法
•對個listint> 進行求和我們這里假設List的長度為listLength
復制代碼 代碼如下:
Parallel.Forlong>(0, listLength, () => 0, (j, loop, subsum) =>
{
subsum += lista[j];
return subsum;
}, (x) => Interlocked.Add(ref sum, x));
•在現(xiàn)實中我們也經(jīng)常會遇到需要取消循環(huán)的情況。比如你在隊列中查找一個數(shù)。那么如何退出Parallel.For 循環(huán)了。是不是也是和for 和foreach那樣 使用Break關(guān)鍵字就可以了,答案否定的。這是因為break 構(gòu)造對循環(huán)是有效的,而并行循環(huán)其實是一個方法,并不是循環(huán) 那么要怎么樣取消了。請看下面的例子
復制代碼 代碼如下:
Parallel.Forlong>(0, listLength, () => 0, (j, loop, subsum) =>
{
if (subsum > 20000)
{
loop.Break();
}
subsum += lista[j];
return subsum;
}, (x) => Interlocked.Add(ref sum, x));
• 簡單Parallel.ForEach 循環(huán) Parallel.ForEach循環(huán)的工作方式類似于 Parallel.For 循環(huán) 根據(jù)系統(tǒng)環(huán)境,對源集合進行分區(qū),并在多個線程上計劃工作。 系統(tǒng)中的處理器越多,并行方法的運行速度越快。 對于某些源集合,順序循環(huán)可能更快,具體取決于源的大小和正在執(zhí)行的工作類型
復制代碼 代碼如下:
Parallel.ForEach(lista, i => { dosameting(); });
不知道大家在這個地方有沒有看到foreach的影子。其實上面的例子中的ForEach方法的最后一個輸入?yún)?shù)是 Actionint>委托,當所有循環(huán)完成時,方法將調(diào)用該委托。這個地方和前面的Parallel.For 是一樣的。那么我們要如何獲得返回值了和上面的For是非常相似,我依然以上面數(shù)組求和為例
復制代碼 代碼如下:
Parallel.ForEachint, long>(lista, () => 0, (j, loop, subsum) =>
{
if (subsum > 20000)
{
loop.Break();
}
subsum += lista[j];
return subsum;
}, (x) => Interlocked.Add(ref sum, x));
• Parallel.For 和for 性能測試比較 我們這里產(chǎn)生1千萬個隨機數(shù)為例子做個一個性能比較,在筆者的筆記本上結(jié)果如下 (可能在你的電腦上得到結(jié)果不一定相同)
附上相關(guān)的代碼給大家參考
復制代碼 代碼如下:
int listLength = 10000000;
Listint> listTask = new Listint>();
Listint> list = new Listint>();
Stopwatch watch1 = Stopwatch.StartNew();
Parallel.For(0, listLength, i => {
Random r = new Random(100);
listTask.Add(r.Next());
});
Console.WriteLine("并行耗時:" + watch1.ElapsedMilliseconds );
Stopwatch watch2 = Stopwatch.StartNew();
for (int i = 0; i listLength; i++)
{
Random r = new Random(100);
list.Add(r.Next());
}
Console.WriteLine("非并行耗時:" + watch2.ElapsedMilliseconds );
您可能感興趣的文章:- js數(shù)值計算時使用parseInt進行數(shù)據(jù)類型轉(zhuǎn)換(jquery)
- 用asp實現(xiàn)訪問遠程計算機上MDB access數(shù)據(jù)庫文件的方法
- Access使用查詢--1.2.用選擇查詢進行分組數(shù)據(jù)的計算
- 數(shù)據(jù)計算中間件技術(shù)綜述