成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

共享內(nèi)存 & Actor并發(fā)模型到底哪個快?

存儲 存儲軟件
共享內(nèi)存利用多核CPU的優(yōu)勢,使用強一致的鎖機制控制并發(fā), 各種鎖交織,稍不注意可能出現(xiàn)死鎖,更適合熟手。

[[414358]]

本文轉(zhuǎn)載自微信公眾號「精益碼農(nóng)」,作者有態(tài)度的馬甲。轉(zhuǎn)載本文請聯(lián)系精益碼農(nóng)公眾號。

先說結(jié)論

1.首先兩者對于并發(fā)的風(fēng)格模型不一樣。

共享內(nèi)存利用多核CPU的優(yōu)勢,使用強一致的鎖機制控制并發(fā), 各種鎖交織,稍不注意可能出現(xiàn)死鎖,更適合熟手。

Actor模型易于控制和管理,以消息觸發(fā)、流水線挨個處理,天然分布式,思路清晰。

2.真要說性能,求100_000 以內(nèi)的素數(shù)的個數(shù)]場景 & 電腦8c 16g的配置

  • 2.1 理論上如果以默認(rèn)的Actor并發(fā)模型來做這個事情,共享內(nèi)存模型是優(yōu)于Actor模型的;
  • 2.2 上文中我對于Actor做了多線程優(yōu)化,Actor模型性能慢慢追上來了。

下面請聽我嘮嗑。

默認(rèn)Actor模型

計算[100_000內(nèi)素數(shù)的個數(shù)], 分為兩步:

(1) 迭代判斷當(dāng)前數(shù)字是不是素數(shù)

(2) 如果是素數(shù),執(zhí)行sum++

完成以上兩步,共享內(nèi)存模型均能充分利用CPU多核心。

Actor模型:與TPL中的原語不同,TPL Datflow中的所有塊默認(rèn)是單線程的,這就意味著完成以上兩步的TransfromBlock和ActionBlock都是以一個線程挨個處理消息數(shù)據(jù) (這也是Dataflow的設(shè)計初衷,形成清晰單純的流水線)。

猜測此時:共享內(nèi)存相比默認(rèn)的Actor模型更具優(yōu)勢。

使用NUnit做單元測試,數(shù)據(jù)量從小到大: 10_000,50_000,100_000,200_000,300_000,500_000

  1. using NUnit.Framework; 
  2. using System; 
  3. using System.Threading.Tasks; 
  4. using System.Collections.Generic; 
  5. using System.Threading; 
  6. using System.Threading.Tasks.Dataflow; 
  7.  
  8. namespace TestProject2 
  9.     public class Tests 
  10.     { 
  11.         [TestCase(10_000)] 
  12.         [TestCase(50_000)] 
  13.         [TestCase(100_000)] 
  14.         [TestCase(200_000)] 
  15.         [TestCase(300_000)] 
  16.         [TestCase(500_000)] 
  17.         public void ShareMemory(int num) 
  18.         { 
  19.             var sum = 0; 
  20.             Parallel.For(1, num + 1, (x, state) => 
  21.             { 
  22.                 var f = true
  23.                 if (x == 1) 
  24.                     f = false
  25.                 for (int i = 2; i <= x / 2; i++) 
  26.                 { 
  27.                     if (x % i == 0)  // 被[2,x/2]任一數(shù)字整除,就不是質(zhì)數(shù) 
  28.                         f = false
  29.                 } 
  30.                 if (f == true
  31.                 { 
  32.                     Interlocked.Increment(ref sum);// 共享了sum對象,“++”就是調(diào)用sum對象的成員方法 
  33.                 } 
  34.             }); 
  35.             Console.WriteLine($"1-{num}內(nèi)質(zhì)數(shù)的個數(shù)是{sum}"); 
  36.         } 
  37.  
  38.         [TestCase(10_000)] 
  39.         [TestCase(50_000)] 
  40.         [TestCase(100_000)] 
  41.         [TestCase(200_000)] 
  42.         [TestCase(300_000)] 
  43.         [TestCase(500_000)] 
  44.         public async Task Actor(int num) 
  45.         { 
  46.             var linkOptions = new DataflowLinkOptions { PropagateCompletion = true }; 
  47.             var bufferBlock = new BufferBlock<int>(); 
  48.             var transfromBlock = new TransformBlock<int, bool>(x => 
  49.             { 
  50.                 var f = true
  51.                 if (x == 1) 
  52.                     f = false
  53.                 for (int i = 2; i <= x / 2; i++) 
  54.                 { 
  55.                     if (x % i == 0)  // 被[2,x/2]任一數(shù)字整除,就不是質(zhì)數(shù) 
  56.                         f = false
  57.                 } 
  58.                 return f; 
  59.             }, new ExecutionDataflowBlockOptions { EnsureOrdered = false }); 
  60.  
  61.             var sum = 0; 
  62.             var actionBlock = new ActionBlock<bool>(x => 
  63.             { 
  64.                 if (x == true
  65.                     sum++; 
  66.             }, new ExecutionDataflowBlockOptions {  EnsureOrdered = false }); 
  67.             transfromBlock.LinkTo(actionBlock, linkOptions); 
  68.             // 準(zhǔn)備從pipeline頭部開始投遞 
  69.             try 
  70.             { 
  71.                 var list = new List<int> { }; 
  72.                 for (int i = 1; i <= num; i++) 
  73.                 { 
  74.                     var b = await transfromBlock.SendAsync(i); 
  75.                     if (b == false
  76.                     { 
  77.                         list.Add(i); 
  78.                     } 
  79.                 } 
  80.                 if (list.Count > 0) 
  81.                 { 
  82.                     Console.WriteLine($"md,num post failure,num:{list.Count},post again"); 
  83.                     // 再投一次 
  84.                     foreach (var item in list) 
  85.                     { 
  86.                         transfromBlock.Post(item); 
  87.                     } 
  88.                 } 
  89.                 transfromBlock.Complete();  // 通知頭部,不再投遞了; 會將信息傳遞到下游。 
  90.                 actionBlock.Completion.Wait();  // 等待尾部執(zhí)行完 
  91.                 Console.WriteLine($"1-{num} Prime number include {sum}"); 
  92.             } 
  93.             catch (Exception ex) 
  94.             { 
  95.                 Console.WriteLine($"1-{num} cause exception.",ex); 
  96.             }    
  97.         } 
  98.     } 

測試結(jié)果如下:

測試結(jié)果印證我說的結(jié)論2.1

優(yōu)化后的Actor模型

那后面我對Actor做了什么優(yōu)化呢? 能產(chǎn)生下圖的2.2結(jié)論。

請重新回看《三分鐘掌握共享內(nèi)存 & Actor并發(fā)模型》 TransfromBlock 塊的細(xì)節(jié):

  1. var transfromBlock = new TransformBlock<int, bool>(x => 
  2.     { 
  3.           var f = true
  4.           if (x == 1) 
  5.              f = false
  6.           for (int i = 2; i <= x / 2; i++) 
  7.           { 
  8.                 if (x % i == 0)  // 被[2,x/2]任一數(shù)字整除,就不是質(zhì)數(shù) 
  9.                    f = false
  10.            } 
  11.            return f; 
  12.      }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism=50, EnsureOrdered = false }); // 這里開啟多線程并發(fā) 

上面說到默認(rèn)的Actor是以單線程處理輸入的消息,此次我們對這個TransfromBlock 塊設(shè)置了MaxDegreeOfParallelism 參數(shù),

這個參數(shù)能在Actor中開啟多線程并發(fā)執(zhí)行,但是這里面就不能有共享變量(否則你又得加鎖),恰好我們完成 (1) 迭代判斷當(dāng)前數(shù)字是不是素數(shù)這一步并不依賴共享對象,所以這(1)步開啟多線程以后性能與共享內(nèi)存模型基本沒差別。

那為什么總體性能慢慢超過共享內(nèi)存?

這是因為執(zhí)行第二步(2) 如果是素數(shù),執(zhí)行sum++, 共享內(nèi)存要加/解鎖,線程切換; 而Actor單線程挨個處理, 總體上Actor就略勝共享內(nèi)存模型了。

這里再次強調(diào),Actor模型執(zhí)行第二步(2) 如果是素數(shù),執(zhí)行sum++,不可開啟MaxDegreeOfParallelism,因為依賴了共享變量sum

結(jié)束語

That's All, 感謝.NET圈紀(jì)檢委@懶得勤快促使我重溫了單元測試的寫法 & 深度分析Actor模型風(fēng)格。 

請大家仔細(xì)對比結(jié)論和上圖,脫離場景和硬件環(huán)境談性能就是耍流氓,理解不同并發(fā)模型的風(fēng)格和能力是關(guān)鍵, 針對場景和未來的拓展性、可維護性、可操作性做技術(shù)選型 。

 

責(zé)任編輯:武曉燕 來源: 精益碼農(nóng)
相關(guān)推薦

2023-08-10 08:01:36

RDB數(shù)據(jù)AOF

2020-09-23 22:36:27

分布式架構(gòu)系統(tǒng)

2021-07-06 14:47:30

Go 開發(fā)技術(shù)

2018-12-18 14:08:01

Java內(nèi)存volatile

2012-11-15 10:18:11

IBMdw

2020-09-22 08:22:28

快充

2022-10-27 08:31:31

架構(gòu)

2016-09-26 17:09:28

Java并發(fā)編程內(nèi)存模型

2009-08-05 16:04:27

C# Actor模型

2022-02-21 10:18:13

機器學(xué)習(xí)數(shù)據(jù)模型

2010-01-15 09:15:09

Scala Actor并發(fā)

2023-10-27 07:47:58

Java語言順序性

2017-03-02 14:52:46

2021-07-26 08:12:31

開源API網(wǎng)關(guān)

2022-03-16 08:39:19

StackHeap內(nèi)存

2009-07-09 10:02:39

Actor模型Erlang

2022-06-07 12:03:33

Java內(nèi)存模型

2018-04-25 10:13:30

Redis內(nèi)存模型

2023-05-28 13:03:46

BeegoGin設(shè)計

2019-07-27 09:40:56

MySQLPG數(shù)據(jù)庫
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久精品视频12 | 精品91久久| 欧美黄色免费网站 | 久久精品久久久久久 | 亚洲国产一区二区三区四区 | 国产精品日韩欧美一区二区 | 日韩精品一区二区三区中文在线 | 观看av | 美女福利网站 | 九色网址 | 播放一级黄色片 | 区一区二区三在线观看 | 国产在视频一区二区三区吞精 | 国产精品一区在线 | 亚洲福利视频一区二区 | 欧美激情在线观看一区二区三区 | 福利二区 | 精品伊人久久 | 久久99精品国产麻豆婷婷 | 日韩国产精品一区二区三区 | 精品国产一区二区在线 | 又黄又色| 日韩精品在线视频免费观看 | 精品欧美一区免费观看α√ | 欧美在线播放一区 | 久久久久国产精品一区三寸 | 99热视| 国产亚洲精品美女久久久久久久久久 | 亚洲色图网址 | 国产精品久久久久久妇女6080 | 欧美日韩专区 | 日韩欧美国产精品一区二区三区 | 国产日产久久高清欧美一区 | 中文字幕一区在线观看视频 | 中文字幕国产视频 | 国产线视频精品免费观看视频 | 国产精品综合视频 | 午夜日韩视频 | 欧美日韩精品一区二区三区蜜桃 | www.国产一区| 日本精品一区二区三区视频 |