閱讀目錄:
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名申請、網(wǎng)頁空間、營銷軟件、網(wǎng)站建設(shè)、珙縣網(wǎng)站維護(hù)、網(wǎng)站推廣。
1.開篇介紹
2.NET并行計(jì)算基本介紹
3.并行循環(huán)使用模式
3.1并行For循環(huán)
3.2并行ForEach循環(huán)
3.3并行LINQ(PLINQ)
最近這幾天在搗鼓并行計(jì)算,發(fā)現(xiàn)還是有很多值得分享的意義,因?yàn)槲覀儸F(xiàn)在很多人對它的理解還是有點(diǎn)不準(zhǔn)確,包括我自己也是這么覺得,所以整理一些文章分享給在使用.NET并行計(jì)算的朋友和將要使用.NET并行計(jì)算的朋友;
NET并行編程推出已經(jīng)有一段時(shí)間了,在一些項(xiàng)目代碼里也時(shí)不時(shí)會看見一些眼熟的并行計(jì)算代碼,作為熱愛技術(shù)的我們怎能視而不見呢,于是搗鼓了一番跟自己的理解恰恰相反,看似一段能提高處理速度的并行代碼為能起效果,跟直接使用手動創(chuàng)建的后臺線程處理差不多,這不太符合我們對.NET并行的強(qiáng)大技術(shù)的理解,所以自己搞了點(diǎn)資料看看,實(shí)踐了一下,發(fā)現(xiàn)在使用.NET并行技術(shù)的時(shí)候需要注意一些細(xì)節(jié),這些細(xì)節(jié)看代碼是看不出來的,所以我們看到別人這么用我們就模仿這么用,我們需要自己去驗(yàn)證一下到底能提高多少處理速度和它的優(yōu)勢在哪里;要不然效率上不去反而還低下,查看代碼也不能很好的斷定哪里出了問題,所以還是需要系統(tǒng)的學(xué)習(xí)總結(jié)才行;
現(xiàn)在的系統(tǒng)已經(jīng)不在是以前桌面程序了,也不是簡單的WEB應(yīng)用系統(tǒng),而是大型的互聯(lián)網(wǎng)社區(qū)、電子商務(wù)等大型系統(tǒng),具有高并發(fā),大數(shù)據(jù)、SOA這些相關(guān)特性的復(fù)雜體系的綜合性開放平臺;.NET作為市場占有率這么高的開發(fā)技術(shù),有了一個(gè)很強(qiáng)大的并行處理技術(shù),目的就是為了能在高并發(fā)的情況下提高處理效率,提高了單個(gè)并發(fā)的處理效率也就提高了總體的系統(tǒng)的吞吐量和并發(fā)數(shù)量,在單位時(shí)間內(nèi)處理的數(shù)據(jù)量將提高不是一個(gè)系數(shù)兩個(gè)系數(shù);一個(gè)處理我們提高了兩倍到三倍的時(shí)間,那么在并發(fā)1000萬的頂峰時(shí)時(shí)不時(shí)很客觀;
既然是.NET并行計(jì)算,那么我們首先要弄清楚什么叫并行計(jì)算,與我們以前手動創(chuàng)建多線程的并行計(jì)算有何不同,好處在哪里;我們先來了解一下什么是并行計(jì)算,其實(shí)簡單形容就是將一個(gè)大的任務(wù)分解成多個(gè)小任務(wù),然后讓這些小任務(wù)同時(shí)的進(jìn)行處理,當(dāng)然純屬自己個(gè)人理解,當(dāng)然不是很全面,但是我們使用者來說足夠了;
在以前單個(gè)CPU的情況下只能靠提高CPU的時(shí)鐘頻率,但是畢竟是有極限的,所以現(xiàn)在基本上是多核CPU,個(gè)人筆記本都已經(jīng)基本上是4核了,服務(wù)器的話都快上20了;在這樣一個(gè)有利的計(jì)算環(huán)境下,我們的程序在處理一個(gè)大的任務(wù)時(shí)為了提高處理速度需要手動的將它分解然后創(chuàng)建Thread來處理,在.NET中我們一般都會自己創(chuàng)建Thread來處理單個(gè)子任務(wù),這大家都不陌生,但是我們面臨的問題就是不能很好的把握創(chuàng)建Thread的個(gè)數(shù)和一些參數(shù)的控制,畢竟.NET并行也是基于以前的Thread來寫的,如何在多線程之間控制參數(shù),如何互斥的執(zhí)行的線程順序等等問題,導(dǎo)致我們不能很好的使用Thread,所以這個(gè)時(shí)候.NET并行框架為我們提供了一個(gè)很好的并行開發(fā)平臺,畢竟大環(huán)境就是多核時(shí)代;
下面我們將接觸.NET并行計(jì)算中的第一個(gè)使用模式,有很多并行計(jì)算場景,歸結(jié)起來是一系列使用模式;
并行循環(huán)模式就是將一個(gè)大的循環(huán)任務(wù)分解成多個(gè)同時(shí)并行執(zhí)行的小循環(huán),這個(gè)模式很實(shí)用;我們大部分處理程序的邏輯都是在循環(huán)和判斷之間,并行循環(huán)模式可以適當(dāng)?shù)母纳莆覀冊诓僮鞔罅垦h(huán)邏輯的效率;
我們看一個(gè)簡單的例子,看到底提升了多少CPU利用率和執(zhí)行時(shí)間;
using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Diagnostics; namespace ConsoleApplication1.Data { public class DataOperation { private static List<Order> orders = new List<Order>(); static DataOperation() { for (int i = 0; i < 9000000; i++) { orders.Add(new Order() { Oid = Guid.NewGuid().ToString(), OName = "OrderName_" + i.ToString() }); } } public void Operation() { Console.WriteLine("Please write start keys:"); Console.ReadLine(); Stopwatch watch = new Stopwatch(); watch.Start(); orders.ForEach(order => { order.IsSubmit = true; int count = 0; for (int i = 0; i < 2000; i++) { count++; } }); watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); } public void TaskOperation() { Console.WriteLine("Please write start keys:"); Console.ReadLine(); Stopwatch watch = new Stopwatch(); watch.Start(); Parallel.ForEach(orders, order => { order.IsSubmit = true; int count = 0; for (int i = 0; i < 2000; i++) { count++; } }); watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); } } }
這里的代碼其實(shí)很簡單,在靜態(tài)構(gòu)造函數(shù)中我初始化了九百萬條測試數(shù)據(jù),其實(shí)就是Order類型的實(shí)例,這在我們實(shí)際應(yīng)用中也很常見,只不過不是一次性的讀取這么多數(shù)據(jù)而已,但是處理的方式基本上差不多的;然后有兩個(gè)方法,一個(gè)是Operation,一個(gè)是TaskOperation,前者順序執(zhí)行,后者并行執(zhí)行;
在循環(huán)的內(nèi)部我加上了一個(gè)2000的簡單空循環(huán)邏輯,為什么要這么做后面會解釋介紹(小循環(huán)并行模式不會提升性能反而會降低性能);這里是為了讓模擬場景更真實(shí)一點(diǎn);
我們來看一下測試相關(guān)的數(shù)據(jù):i5、4核測試環(huán)境,執(zhí)行時(shí)間為42449毫秒,CPU使用率為25%左右,4核中只使用了1和3的,而其他的都屬于一般處理狀態(tài);
圖1:
我們再來看一下使用并行計(jì)算后的相關(guān)數(shù)據(jù):i5、4核測試環(huán)境,執(zhí)行時(shí)間為19927毫秒,CPU利用率為100%,4核中全部到達(dá)頂峰;
圖2:
這一個(gè)簡單的測試?yán)樱?dāng)然我只測試了兩三組數(shù)據(jù),基本上并行計(jì)算的速度要快于單線程的處理速度的2.1倍以上,當(dāng)然還有其他因素在里面這里就不仔細(xì)分析了,起到拋磚引玉的作用;
在使用for循環(huán)的時(shí)候有相應(yīng)的Parallel方式使用for循環(huán),我們直接看一下示例代碼,還是以上面的測試數(shù)據(jù)為例;
Parallel.For(0, orders.Count, index => { // });
第一個(gè)參數(shù)是索引的開始,第二個(gè)參數(shù)是循環(huán)總數(shù),第三個(gè)是執(zhí)行體,參數(shù)是索引值;使用起來其實(shí)很簡單的;
同樣ForEach也是很簡單的,還是使用上面的測試數(shù)據(jù)為例;
Parallel.ForEach(orders, order => { order.IsSubmit = true; int count = 0; for (int i = 0; i < 2000; i++) { count++; } });
在Parallel類中有ForEach方法,第一個(gè)參數(shù)是迭代集合,第二個(gè)是每次迭代的item;
其實(shí)Parallel為我們封裝了一個(gè)簡單的調(diào)用入口,其實(shí)是依附于后臺的Task框架的,因?yàn)槲覀兂S玫木褪茄h(huán)比較多,畢竟循環(huán)是任務(wù)的入口調(diào)用,所以我們使用并行循環(huán)的時(shí)候還是很方便的;
首先PLINQ是只針對Linq to Object的,所以不要誤以為它也可以使用于Linq to Provider,當(dāng)然自己可以適當(dāng)?shù)姆庋b;現(xiàn)在LINQ的使用率已經(jīng)很高了,我們在做對象相關(guān)的操作時(shí)基本上都在使用LINQ,很方便,特別是Select、Where非常的常用,所以.NET并行循環(huán)也在LINQ上進(jìn)行了一個(gè)封裝,讓我們使用LINQ的時(shí)候很簡單的使用并行特性;
LINQ核心原理的文章:http://www.cnblogs.com/wangiqngpei557/category/421145.html
根據(jù)LINQ的相關(guān)原理,知道LINQ是一堆擴(kuò)展方法的鏈?zhǔn)秸{(diào)用,PLINQ就是擴(kuò)展方法的集合,位于System.Linq.ParallelEnumerable靜態(tài)類中,擴(kuò)展于ParallelQuery<TSource>泛型類;
System.Linq.ParallelQuery<TSource>類:
using System.Collections; using System.Collections.Generic; namespace System.Linq { // 摘要: // 表示并行序列。 // // 類型參數(shù): // TSource: // 源序列中的元素的類型。 public class ParallelQuery<TSource> : ParallelQuery, IEnumerable<TSource>, IEnumerable { // 摘要: // 返回循環(huán)訪問序列的枚舉數(shù)。 // // 返回結(jié)果: // 循環(huán)訪問序列的枚舉數(shù)。 public virtual IEnumerator<TSource> GetEnumerator(); } }
System.Linq.ParallelEnumerable類:
// 摘要: // 提供一組用于查詢實(shí)現(xiàn) ParallelQuery{TSource} 的對象的方法。 這是 System.Linq.Enumerable 的并行等效項(xiàng)。 public static class ParallelEnumerable
我們在用的時(shí)候只需要將它原本的類型轉(zhuǎn)換成ParallelQuery<TSource>類型就行了;
var items = from item in orders.AsParallel() where item.OName.Contains("1") select item;
Linq 的擴(kuò)展性真的很方便,可以隨意的封裝任何跟查詢相關(guān)的接口;
作者:王清培
出處:http://wangqingpei557.blog.51cto.com/
本文版權(quán)歸作者和51CTO共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
當(dāng)前名稱:.NET并行編程實(shí)踐(一:.NET并行計(jì)算基本介紹、并行循環(huán)使用模式)
瀏覽地址:http://www.rwnh.cn/article30/gsjhso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、企業(yè)網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、品牌網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)