十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这期内容当中小编将会给大家带来有关DotNet中怎么实现并行计算,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
专注于为中小企业提供成都网站设计、成都做网站服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业乌鲁木齐免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
误区三 . 并行计算是运行时的事
的确,DotNet会在运行时决定是否使用并行库处理代码,但是早在你编译代码时,编译器就早已为这一时刻做好准备,换就话说:
1. 使用并行库处理代码与普通方式对比,IL的结构是不同的。
2. 即使你选择使用并行计算,并且你也确实拥有多核(线程)CPU,运行时你的代码也不一定是并行的。
使用TPL后CLR可能会分解任务,这一依据的其中之一是由IL支持的,IL将并行的任务代码分离,以便在将来的操作中并行,这一点可以从以下的示例中看出来,以下两段示例的核心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是直接出现在Load方法中的。
再来看看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'::'b__0'(int32) IL_0029: newobj instance void class [mscorlib]System.Action`1 ::.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 ) IL_0033: pop IL_0034: ldloc.0 IL_0035: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop() //注意,Sleep已经不在Load方法中了,而是被一个“b__0”代替,并行代码与宿主代码分离,以下就是b__0的 IL: .method public hidebysig instance void ' 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'::' b__0'
结构图:
以上的红色代码就是在Code A中出现的主要代码。再让我们重温一下这张图,IL的代码任务已经很明显的指示了出来。
每当我们增加一个并行代码段,IL中就会增加一个b_N块:假如我们的代码中包含两个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'::'b__0'(int32) IL_0029: newobj instance void class [mscorlib]System.Action`1 ::.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 ) 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'::' b__1'(int32) IL_003e: newobj instance void class [mscorlib]System.Action`1 ::.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 ) IL_0048: pop IL_0049: ldloc.0 IL_004a: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()
下图中会有对应模块出现:
上述就是小编为大家分享的DotNet中怎么实现并行计算了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。