自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

DotNet并行計(jì)算的使用誤區(qū)二

開(kāi)發(fā) 后端
.NET是一個(gè)微軟開(kāi)發(fā)的編程環(huán)境,里面可以使用C#,VB等多種編程語(yǔ)言。本文主要介紹.NET中,也就是DOTNET中的并行計(jì)算。讓我們一起來(lái)看。

并行計(jì)算或稱平行計(jì)算是相對(duì)于串行計(jì)算來(lái)說(shuō)的。所謂并行計(jì)算可分為時(shí)間上的并行和空間上的并行。 時(shí)間上的并行就是指流水線技術(shù),而空間上的并行則是指用多個(gè)處理器并發(fā)的執(zhí)行計(jì)算。

上接 DotNet并行計(jì)算的使用誤區(qū)一

誤區(qū)三 . 并行計(jì)算是運(yùn)行時(shí)的事

的確,DotNet會(huì)在運(yùn)行時(shí)決定是否使用并行庫(kù)處理代碼,但是早在你編譯代碼時(shí),編譯器就早已為這一時(shí)刻做好準(zhǔn)備,換就話說(shuō):

1. 使用并行庫(kù)處理代碼與普通方式對(duì)比,IL的結(jié)構(gòu)是不同的。

2. 即使你選擇使用并行計(jì)算,并且你也確實(shí)擁有多核(線程)CPU,運(yùn)行時(shí)你的代碼也不一定是并行的。

使用TPL后CLR可能會(huì)分解任務(wù),這一依據(jù)的其中之一是由IL支持的,IL將并行的任務(wù)代碼分離,以便在將來(lái)的操作中并行,這一點(diǎn)可以從以下的示例中看出來(lái),以下兩段示例的核心C#代碼都是Tostring()和Sleep(),Code A使用For包含Sleep,Code B使用Parallel.For處理:

Code Part A:

IL:

  1. IL_000e: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()   
  2. IL_0013: nop   
  3. IL_0014: ldc.i4.0   
  4. IL_0015: stloc.2   
  5. IL_0016: br.s IL_0031   
  6. IL_0018: nop   
  7. IL_0019: ldloca.s i   
  8. IL_001b: call instance string [mscorlib]System.Int32::ToString()   
  9. IL_0020: stloc.0   
  10. IL_0021: ldc.i4 0xc8   
  11. IL_0026: call void [mscorlib]System.Threading.Thread::Sleep(int32)   
  12. IL_002b: nop   
  13. IL_002c: nop   
  14. IL_002d: ldloc.2   
  15. IL_002e: ldc.i4.1   
  16. IL_002f: add   
  17. IL_0030: stloc.2   
  18. IL_0031: ldloc.2   
  19. IL_0032: ldc.i4.s 10   
  20. IL_0034: clt   
  21. IL_0036: stloc.3   
  22. IL_0037: ldloc.3   
  23. IL_0038: brtrue.s IL_0018   
  24. IL_003a: ldloc.1   
  25. IL_003b: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()   

我們注意到,Code Part A的Sleep是直接出現(xiàn)在Load方法中的。

 

再來(lái)看看Parallel方式:

Code Part B:

Form1_Load:

 

  1. IL_0019: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()   
  2. IL_001e: nop   
  3. IL_001f: ldc.i4.0   
  4. IL_0020: ldc.i4.s 10   
  5. IL_0022: ldloc.1   
  6. IL_0023: ldftn instance void WindowsFormsApplication4.Form1/'<>c__DisplayClass1'::'<Form1_Load>b__0'(int32)   
  7. IL_0029: newobj instance void class [mscorlib]System.Action`1<int32>::.ctor(object, native int) IL_002e: call valuetype [mscorlib]System.Threading.Tasks.ParallelLoopResult [mscorlib]System.Threading.Tasks.Parallel::For(int32, int32, class [mscorlib]System.Action`1<int32>)   
  8. IL_0033: pop   
  9. IL_0034: ldloc.0   
  10. IL_0035: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()   
  11. //注意,Sleep已經(jīng)不在Load方法中了,而是被一個(gè)“b__0”代替,并行代碼與宿主代碼分離,以下就是b__0的  
  12. IL: .method public hidebysig instance void '<Form1_Load>b__0'(int32 i) cil managed   
  13. {   
  14. // 代碼大小 26 (0x1a)   
  15. .maxstack 8   
  16. IL_0000: nop   
  17. IL_0001: ldarg.0   
  18. IL_0002: ldarga.s i   
  19. IL_0004: call instance string [mscorlib]System.Int32::ToString()   
  20. IL_0009: stfld string WindowsFormsApplication4.Form1/'<>c__DisplayClass1'::a IL_000e: ldc.i4 0xc8   
  21. IL_0013: call void [mscorlib]System.Threading.Thread::Sleep(int32)   
  22. IL_0018: nop   
  23. IL_0019: ret   
  24. // end of method '<>c__DisplayClass1'::'<Form1_Load>b__0'   
  25.  

 

結(jié)構(gòu)圖:

 

以上的紅色代碼就是在Code A中出現(xiàn)的主要代碼。再讓我們重溫一下這張圖,IL的代碼任務(wù)已經(jīng)很明顯的指示了出來(lái)。

 

每當(dāng)我們?cè)黾右粋€(gè)并行代碼段,IL中就會(huì)增加一個(gè)b_N塊:假如我們的代碼中包含兩個(gè)Parallel塊,每塊的主代碼與上述一致,IL如下:

 

  1. IL_0019: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()   
  2. IL_001e: nop   
  3. IL_001f: ldc.i4.0   
  4. IL_0020: ldc.i4.s 10   
  5. IL_0022: ldloc.1 IL_0023: ldftn instance void WindowsFormsApplication4.Form1/'<>c__DisplayClass2'::'<Form1_Load>b__0'(int32)   
  6. IL_0029: newobj instance void class [mscorlib]System.Action`1<int32>::.ctor(object, native int) IL_002e: call valuetype [mscorlib]System.Threading.Tasks.ParallelLoopResult [mscorlib]System.Threading.Tasks.Parallel::For(int32, int32, class [mscorlib]System.Action`1<int32>)   
  7. IL_0033: pop  
  8. IL_0034: ldc.i4.0   
  9. IL_0035: ldc.i4.s 10   
  10. IL_0037: ldloc.1   
  11. IL_0038: ldftn instance void WindowsFormsApplication4.Form1/'<>c__DisplayClass2'::'<Form1_Load>b__1'(int32)   
  12. IL_003e: newobj instance void class [mscorlib]System.Action`1<int32>::.ctor(object, native int) IL_0043: call valuetype [mscorlib]System.Threading.Tasks.ParallelLoopResult [mscorlib]System.Threading.Tasks.Parallel::For(int32, int32, class [mscorlib]System.Action`1<int32>)   
  13. IL_0048: pop   
  14. IL_0049: ldloc.0   
  15. IL_004a: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()   
  16.  

 

下圖中會(huì)有對(duì)應(yīng)模塊出現(xiàn):

 

上面的例子說(shuō)明,在IL階段已經(jīng)為運(yùn)行時(shí)的并行執(zhí)行任務(wù)做了準(zhǔn)備,編譯階段將并行任務(wù)從宿主中分離出來(lái),運(yùn)行階段決定是否采用并行方式執(zhí)行任務(wù)。

【編輯推薦】

  1. 3.9.3 云計(jì)算與并行計(jì)算
  2. 1.4 商業(yè)應(yīng)用的并行計(jì)算
  3. 1.3 網(wǎng)格計(jì)算:分布式并行計(jì)算
  4. 并行計(jì)算的難點(diǎn)與數(shù)學(xué)原理解析

 

責(zé)任編輯:于鐵 來(lái)源: 博客園
相關(guān)推薦

2011-04-20 17:15:21

并行計(jì)算

2019-04-18 09:15:05

DaskPython計(jì)算

2010-03-22 14:45:40

云計(jì)算

2014-04-24 10:25:15

2021-06-01 05:51:37

云計(jì)算并行計(jì)算分布式計(jì)算

2014-01-21 11:16:59

MPI并行計(jì)算

2012-08-17 09:32:52

Python

2009-12-18 09:38:27

.NET 4.0并行計(jì)

2010-03-19 17:23:45

云計(jì)算

2023-10-30 08:57:19

.Net開(kāi)發(fā)并行計(jì)算

2010-06-11 08:52:17

并行計(jì)算

2011-08-29 10:40:02

浪潮英特爾并行計(jì)算

2010-03-11 15:23:44

Visual Stud

2010-06-10 08:37:04

并行計(jì)算

2010-04-21 09:23:09

.NET 4

2017-04-24 12:07:44

Spark大數(shù)據(jù)并行計(jì)算

2024-10-21 16:54:43

NumPyPython并行計(jì)算

2012-12-18 15:33:44

遞歸數(shù)據(jù)并行計(jì)算

2022-07-08 10:59:32

深度學(xué)習(xí)計(jì)算

2016-10-25 16:38:32

天云軟件云計(jì)算張福波
點(diǎn)贊
收藏

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