溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

DotNet中怎么實(shí)現(xiàn)并行計(jì)算

發(fā)布時(shí)間:2021-07-20 14:13:37 來(lái)源:億速云 閱讀:142 作者:Leah 欄目:編程語(yǔ)言

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)DotNet中怎么實(shí)現(xiàn)并行計(jì)算,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

誤區(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:

IL_000e: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()   IL_0013: nop   IL_0014: ldc.i4.0   IL_0015: stloc.2   IL_0016: br.s IL_0031   IL_0018: nop   IL_0019: ldloca.s i   IL_001b: call instance string [mscorlib]System.Int32::ToString()   IL_0020: stloc.0   IL_0021: ldc.i4 0xc8   IL_0026: call void [mscorlib]System.Threading.Thread::Sleep(int32)   IL_002b: nop   IL_002c: nop   IL_002d: ldloc.2   IL_002e: ldc.i4.1   IL_002f: add   IL_0030: stloc.2   IL_0031: ldloc.2   IL_0032: ldc.i4.s 10   IL_0034: clt   IL_0036: stloc.3   IL_0037: ldloc.3   IL_0038: brtrue.s IL_0018   IL_003a: ldloc.1   IL_003b: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()

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

DotNet中怎么實(shí)現(xiàn)并行計(jì)算

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

Code Part B:

Form1_Load:

IL_0019: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()   IL_001e: nop   IL_001f: ldc.i4.0   IL_0020: ldc.i4.s 10   IL_0022: ldloc.1   IL_0023: ldftn instance void WindowsFormsApplication4.Form1/'<>c__DisplayClass1'::'<Form1_Load>b__0'(int32)   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>)   IL_0033: pop   IL_0034: ldloc.0   IL_0035: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()   //注意,Sleep已經(jīng)不在Load方法中了,而是被一個(gè)“b__0”代替,并行代碼與宿主代碼分離,以下就是b__0的  IL: .method public hidebysig instance void '<Form1_Load>b__0'(int32 i) cil managed   {   // 代碼大小 26 (0x1a)   .maxstack 8   IL_0000: nop   IL_0001: ldarg.0   IL_0002: ldarga.s i   IL_0004: call instance string [mscorlib]System.Int32::ToString()   IL_0009: stfld string WindowsFormsApplication4.Form1/'<>c__DisplayClass1'::a IL_000e: ldc.i4 0xc8   IL_0013: call void [mscorlib]System.Threading.Thread::Sleep(int32)   IL_0018: nop   IL_0019: ret   } // end of method '<>c__DisplayClass1'::'<Form1_Load>b__0'

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

DotNet中怎么實(shí)現(xiàn)并行計(jì)算

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

DotNet中怎么實(shí)現(xiàn)并行計(jì)算

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

IL_0019: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()   IL_001e: nop   IL_001f: ldc.i4.0   IL_0020: ldc.i4.s 10   IL_0022: ldloc.1 IL_0023: ldftn instance void WindowsFormsApplication4.Form1/'<>c__DisplayClass2'::'<Form1_Load>b__0'(int32)   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>)   IL_0033: pop  IL_0034: ldc.i4.0   IL_0035: ldc.i4.s 10   IL_0037: ldloc.1   IL_0038: ldftn instance void WindowsFormsApplication4.Form1/'<>c__DisplayClass2'::'<Form1_Load>b__1'(int32)   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>)   IL_0048: pop   IL_0049: ldloc.0   IL_004a: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()

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

DotNet中怎么實(shí)現(xiàn)并行計(jì)算

上述就是小編為大家分享的DotNet中怎么實(shí)現(xiàn)并行計(jì)算了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI