<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 編程語(yǔ)言的發(fā)展趨勢及未來(lái)方向(6):并發(fā)

編程語(yǔ)言的發(fā)展趨勢及未來(lái)方向(6):并發(fā)

作者: 時(shí)間:2017-04-17 來(lái)源:網(wǎng)絡(luò ) 收藏

  這是Anders Hejlsberg(不用介紹這是誰(shuí)了吧)在比利時(shí)TechDays 2010所做的開(kāi)場(chǎng)演講。由于最近我在博客上關(guān)于語(yǔ)言的討論比較多,出于應景,也打算將Anders的演講完整地聽(tīng)寫(xiě)出來(lái)。在上一部分中,Anders談?wù)摿恕霸幊獭奔八谂Φ摹熬幾g器即服務(wù)”功能。在這一部分中,Anders則談?wù)摿恕安l(fā)”,這也是他眼中發(fā)展的三種趨勢之一,并演示了.NET 4.0中并行庫的神奇效果。

本文引用地址:http://dyxdggzs.com/article/201704/346685.htm

  如果沒(méi)有特別說(shuō)明,所有的文字都直接翻譯自Anders的演講,并使用我自己的口語(yǔ)習慣表達出來(lái),對于A(yíng)nders的口誤及反復等情況,必要時(shí)在譯文中自然也會(huì )進(jìn)行忽略。為了方便理解,我也會(huì )將視頻中關(guān)鍵部分進(jìn)行截圖,而某些代碼演示則會(huì )直接作為文章內容發(fā)表。

  (聽(tīng)寫(xiě)開(kāi)始,接上篇)

    

 

  好,最后我想談的內容是“并發(fā)”。

    

 

  聽(tīng)說(shuō)過(guò)摩爾定律的請舉手……幾乎是所有人。那么多少人聽(tīng)說(shuō)了摩爾定律已經(jīng)結束了呢?嗯,還是有很多人。我有好消息,也有壞消息。我認為摩爾定律并沒(méi)有停止。摩爾定律說(shuō)的是:可以在集成電路上低成本地放置晶體管的數目,約每?jì)赡瓯銜?huì )增加一倍。有趣的是,這個(gè)定律從60年代持續到現在,而從一些跡象上來(lái)看,這個(gè)定律會(huì )繼續保持20到30年。

  摩爾定理有個(gè)推論,便是說(shuō)時(shí)鐘速度將根據相同的周期提高,也就是說(shuō)每隔大約24個(gè)月,CPU的速度便會(huì )加倍──而這點(diǎn)已經(jīng)停止了。再來(lái)統計一下,你們之中有誰(shuí)的機器里有20GHz的CPU?看到了沒(méi)?一個(gè)人都沒(méi)有。但如果你從五年前開(kāi)始計算的話(huà),現在我們應該已經(jīng)在使用20GHz的CPU了,但事實(shí)并非如此。這點(diǎn)在五年前就停止了,而且事實(shí)上最大速度還有些下降,因為發(fā)熱量實(shí)在太大了,會(huì )消耗許多能源,讓電池用的太快。

    

 

  有些物理方面的基礎因素讓CPU不能運行的太快。然而,另一意義上的摩爾定理出現了。我們還是可以看到容量的增加,因為可以在同一個(gè)表盤(pán)上放置多個(gè)CPU了。目前已經(jīng)有了雙核、四核,Intel的CTO在三年前說(shuō),十年后我們可以出現80核的處理器。

    

 

  到了那個(gè)時(shí)候,你的任務(wù)管理器中就可能是這樣的。似乎有些嚇人,不過(guò)這是我們實(shí)驗室中真實(shí)存在的128核機器。你可以看到,計算能力已經(jīng)完全用上了。這便是個(gè)問(wèn)題,比如你在這臺強大的機器上進(jìn)行一個(gè)實(shí)驗,你自然希望看到100%的使用狀況,不過(guò)傳統的實(shí)驗都是在一個(gè)核上執行的,所以我們面臨的挑戰是,我們需要換一種寫(xiě)程序的方式來(lái)利用此類(lèi)機器。

  我的一個(gè)同事,Herb Sutter,他寫(xiě)過(guò)一篇文章,談到“免費的午餐已經(jīng)結束了”。沒(méi)錯,我們已經(jīng)不能寫(xiě)一個(gè)程序,然后對客戶(hù)說(shuō):啊,未來(lái)的硬件會(huì )讓它運行的越來(lái)越快,我們不用關(guān)心太多──不,已經(jīng)不會(huì )這樣了,除非你換種不同的寫(xiě)法。實(shí)話(huà)說(shuō),這是個(gè)挑戰,也是個(gè)機遇。說(shuō)它是個(gè)挑戰,是因為并發(fā)十分困難,至今我們對此還沒(méi)有簡(jiǎn)單的答案,稍后我會(huì )演示一些正有所改善的東西,但……這也是一個(gè)機遇,在這樣的機器上,你的確可以用完所有的核,這樣便能獲得性能提高,不過(guò)做法需要有所不同。

  多核革命的一個(gè)有趣之處在于,它對于并發(fā)的思維方式會(huì )有所改變。傳統的并發(fā)思維是在單個(gè)CPU上執行多個(gè)邏輯任務(wù),使用舊有的分時(shí)方式、時(shí)間片模型來(lái)執行多個(gè)任務(wù)。但是,你想一下便會(huì )發(fā)現如今的并發(fā)情況正好相反,現在是要將一個(gè)邏輯上的任務(wù)放在多個(gè)CPU上執行。這改變了我們編寫(xiě)程序的方式,這意味著(zhù)對于語(yǔ)言或是API來(lái)說(shuō),我們需要有辦法來(lái)分解任務(wù),把它拆分成多個(gè)小任務(wù)后獨立的執行,而傳統的中并不關(guān)注這點(diǎn)。

    

 

  使用目前的并發(fā)API來(lái)完成工作并不容易,比如使用Thread,ThreadPool,lock,Monitor等等,你無(wú)法太好的進(jìn)展。不過(guò).NET 4.0提供了一些美妙的事物,我們稱(chēng)之為.NET并行擴展。它是一種現代的并發(fā)模型,將邏輯上的任務(wù)并發(fā)與我們實(shí)際使用的的物理模型分離開(kāi)來(lái)。以前我們的API都是直接處理線(xiàn)程,也就是(上圖)下方橙色的部分,不過(guò)有了.NET并行擴展之后,你可以使用更為邏輯化的編程風(fēng)格。任務(wù)并行庫(Task Parallel Library),并行LINQ(Parallel LINQ)以及協(xié)調數據結構(Coordination Data Structures)讓你可以直接關(guān)注邏輯上的任務(wù),而不必關(guān)心它們是如何運行的,或是使用了多少個(gè)線(xiàn)程和CPU等等。

    

 

  下面我來(lái)簡(jiǎn)單演示一下它們的使用方式。我帶來(lái)了一個(gè)PLINQ演示,這里是一些代碼,讀取XML文件的內容。這有個(gè)50M大小的popname.xml文件,保存了美國社會(huì )安全數據庫里的信息,包含某個(gè)洲在某一年的人口統計信息。這個(gè)程序會(huì )讀取這個(gè)XML文件,把它轉化成一系列對象,并存放在一個(gè)List中。然后對其執行一個(gè)LINQ語(yǔ)句,查找所有在華盛頓名叫Robert的人,再根據年份進(jìn)行排序:

  Console.WriteLine("Loading XML data...");

  var popNames =

  (from e in XElement.Load("popnames.xml").Elements("Name")

  select new

  {

  Name = (string)e.Attribute("Name"),

  State = (string)e.Attribute("State"),

  Year = (int)e.Attribute("Year"),

  Count = (int)e.Attribute("Count")

  })

  .ToList();

  Console.WriteLine(popNames.Count + " records");

  Console.WriteLine();

  string targetName = "Robert";

  string targetState = "WA";

  var querySequential =

  from n in popNames

  where n.Name == targetName && n.State == targetState

  orderby n.Year

  select n;

  我們來(lái)執行一下……首先加載XML文件,然后進(jìn)行查詢(xún)。利用PLINQ我們可以做到并行地查詢(xún)。我們只要拷貝一份代碼……改成queryParallel……現在我唯一要做的只是在數據源上使用AsParallel擴展方法,這樣便會(huì )引入一套新的類(lèi)型和實(shí)現,此時(shí)相同的LINQ操作使用的便是并行的實(shí)現:

  var queryParallel =

  from n in popNames.AsParallel()

  where n.Name == targetName && n.State == targetState

  orderby n.Year

  select n;

  我們重新執行兩個(gè)查詢(xún)。

    

 

  再次加載XML數據……并行實(shí)現使用了1.5秒,我們再試著(zhù)運行一次,一般結果會(huì )更好一些,現在可能剛好在執行一些后臺任務(wù)。一般我們可以得到更快的結果……這次比較接近了?,F在你可以觀(guān)察到,我們并不需要做太多事情,便可以在我的雙核機器上得到并發(fā)的效果。

    

 

  這里我無(wú)法保證說(shuō),我們只要隨時(shí)加上AsParallel便可以得到兩倍的性能,有時(shí)可以有時(shí)不行,有些查詢(xún)能夠被并行,有的則不可以。然而,我想你一定同意一點(diǎn),使用如LINQ這樣的DSL能夠方便我們編寫(xiě)并行的代碼,也更有可能利用起并行效果。雖然不是每次都有效,但是嘗試的成本也很低。如果我們使用普通的for循環(huán)來(lái)編寫(xiě)代碼,在某個(gè)地方使用線(xiàn)程池等等,便很容易在這些API里失去方向。而這里我們只要簡(jiǎn)單地嘗試一下,便能知道是否可以提高性能了。

    

 

  這里你已經(jīng)看到我使用的LINQ查詢(xún),而現在也有很多工作是通過(guò)循環(huán)來(lái)完成的。你可以想象主要的運算是從哪里來(lái)的,很自然會(huì )是在循環(huán)里操作數據。如果循環(huán)的每個(gè)迭代都是獨立的,便有很大的機會(huì )可以利用并發(fā)操作──我知道這里是“如果”,不過(guò)長(cháng)期來(lái)看則一定會(huì )出現這樣的情況。這時(shí)候便可以使用并行擴展,或者說(shuō)是.NET并行擴展里的新API,把循環(huán)轉化成并行的循環(huán),只要簡(jiǎn)單的改變……幾乎只要用同樣的循環(huán)體把for重構成Parallel.For就行了。如果你有foreach操作就可以使用Parallel.ForEach,或是一系列順序執行的語(yǔ)句也可以用上Parallel.Invoke。此時(shí)任務(wù)并行庫會(huì )接管并執行這些任務(wù),根據你的CPU數量使用最優(yōu)化的線(xiàn)程數量,你不需要關(guān)注更深的細節,只需要編寫(xiě)邏輯就可以了。

    

 

  就像我說(shuō)的那樣,可能你會(huì )有獨立的任務(wù)但也可能沒(méi)有,所以很多時(shí)候我們需要來(lái)關(guān)注這方面的事情。比如“隔離性(Isolation)”。例如,編譯器如何發(fā)現這段代碼是獨立的,可以安全地并發(fā)執行,好比我創(chuàng )建了一個(gè)對象,在分享給其他人之前,我對它的改變是安全的。但是我一旦把它們共享出去了,那么它們便不安全了。所以如果我們的類(lèi)型系統可以跟蹤到這樣的共享,如Linear Types──這在學(xué)術(shù)界也有一些研究。我們也可以在函數的純潔性(Purity)方面下功夫,如關(guān)注某個(gè)函數是否有副作用,有些時(shí)候編譯器可以做這方面的檢查,它可以禁止某些操作,以此保證我們寫(xiě)出純函數。還有便是不可變性(Immutability),目前的C#或VB,我們需要額外的工作才能寫(xiě)出不可變的代碼──但本不該這樣,我們應該在語(yǔ)言層面上更好的支持不可變性。這些都是在并發(fā)方面需要考慮的問(wèn)題。

  如果說(shuō)有哪個(gè)語(yǔ)言特性超出這個(gè)范疇,我想說(shuō)這里還有一個(gè)原則:你不該期望C#中出現某個(gè)特別的并發(fā)模型,而應該是一種通用的,可用于各種不同的并發(fā)場(chǎng)景的特性,就像隔離性、純潔性及不可變性那樣。語(yǔ)言擁有這樣的特性之后,就可以用于構建各種不同的API,各種并發(fā)方式都可以利用到核心的語(yǔ)言特性。

  (未完待續)



關(guān)鍵詞: 編程語(yǔ)言

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>