引言
隨着CPU多核的普及,編程時充分利用這個特性越顯重要。本文首先用傳統的嵌套循環進行數組填充,然後用.NET 4.0中的System.Threading.Tasks提供的Parallel Class來並行地進行填充(當然這裏也用到嵌套循環),通過對比發現其中差異。主要內容如下:
- 通常的數組填充
- 並行的組數填充
- 性能比較
- System.Threading.Tasks分析,這個將在續篇.NET(C#) Internals: 以一個數組填充的例子初步瞭解.NET 4.0中的並行(二)中介紹
1、通常的數組填充
首先看如下代碼:
- using System;
- namespace ParallelForSample
- {
- public class SingleCore
- {
- public static void Calculate(int calcVal)
- {
- Utility util = new Utility();
- util.Start();
- int[,] G = new int[calcVal, calcVal];
- for (int k = 0; k < calcVal; k++)
- for (int i = 0; i < calcVal; i++)
- for (int j = 0; j < calcVal; j++)
- G[i, j] = Math.Min(G[i, j], G[i, k] + G[k, j]);
- util.Stop();
- }
- }
- }
上面的粗體紅色顯示的幾行代碼就是實現數組填充,這個很好理解不用多費口舌。補充說明的是:上面的Utility是爲了統計性能而編寫的一個類,它主要就是用到了Stopwatch對象——它提供一組方法和屬性,可用於準確地測量運行時間。Utility的代碼如下:
- public class Utility
- {
- private Stopwatch _stopwatch;
- public void Start()
- {
- _stopwatch = new Stopwatch();
- _stopwatch.Start();
- }
- public void Stop()
- {
- _stopwatch.Stop();
- TimeSpan ts = _stopwatch.Elapsed;
- string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
- ts.Hours, ts.Minutes, ts.Seconds,
- ts.Milliseconds / 10);
- Console.WriteLine("Time taken : {0}", elapsedTime);
- }
- }
利用它我們就可以對數組填充所耗費的時間進行計算了。
2、並行的組數填充
爲了充分利用CPU的多核,我們編寫如下代碼:
- using System;
- using System.Threading.Tasks;
- namespace ParallelForSample
- {
- public class MultiCore
- {
- public static void Calculate(int calcVal)
- {
- Utility util = new Utility();
- util.Start();
- int[,] G = new int[calcVal, calcVal];
- Parallel.For(0, calcVal,
- delegate(int k)
- {
- Parallel.For(0, calcVal, delegate(int i)
- {
- for (int j = 0; j < calcVal; j++)
- G[i, j] = Math.Min(G[i, j], G[i, k] + G[k, j]);
- });
- }
- );
- util.Stop();
- }
- }
- }
留意上面的紅色粗體顯示的幾行代碼,它利用了Parallel.For Method (Int32, Int32, Action<Int32>)方法,Parallel類位於命名空間System.Threading.Tasks中,它支持並行循環。此Parallel.For方法使得它裏面的迭代可能並行地運行,注意到上述代碼中它的第三個參數是一個委託。在(0,calcVal)之間,這個委託將被調用。
3、性能比較
現在我們來測試一下,上面兩種方法的執行性能差異如何,下載源碼。其實,核心代碼已經在上面貼出來了,現在注意是編寫實例來測試,代碼主要如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ParallelForSample
- {
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("Single core");
- SingleCore.Calculate(1000);
- Console.WriteLine("Multi core");
- MultiCore.Calculate(1000);
- Console.WriteLine("Finished");
- Console.ReadKey();
- }
- }
- }
運行之後得到如下結果:(不同電腦配置不同,得出結果不同)
圖1、性能比較
從結果可以看出,並行的數組填充比通常的數組填充性能更高。
- System.Threading.Tasks分析,這個將在續篇.NET(C#) Internals: 以一個數組填充的例子初步瞭解.NET 4.0中的並行(二)中介紹……