2014-02-09 65 views
3

我想在多核虛擬機上測試多線程程序的線程執行情況。我寫了它的C#代碼:關於多核進程怪異結果的多線程

class Program 
{ 
    public static int fib(int n) 
    { 
     if (n < 2) 
      return n; 

     return fib(n-1)+fib(n-2); 
    } 

    public static void execution(object n) 
    { 
     int STEP = 40; 
     var start = DateTime.Now; 
     int value = fib(STEP); 
     var end = DateTime.Now; 

     Console.WriteLine(string.Format("threads: {0}, time : {1}, start: {2}, end: {3}", n, end.Subtract(start).TotalSeconds, 
      start, end)); 
    } 

    static void Main(string[] args) 
    { 
     int[] threads = {1, 2, 4, 8, 16}; 

     for(int j=0; j<5; ++j) 
     { 
      for (int i = 0; i < threads[j]; ++i) 
      { 
       var thread = new Thread(Program.execution); 
       thread.Start(threads[j]); 
      } 
      Thread.Sleep(60000); 
     } 
    } 

,這是我

線程的結果:1,時間:4.2177734,開始:2014年2月8日下午七點30分13秒,結束:2/8/2014 7:30:18 PM

thread:2,time:4.1015625,start:2014/2/8 7:31:13 PM結束:2014/2/8 7:31:17 PM

thread:2,time:4.2441407,start:2014/2/8 7:31:13,結束於:2014/2/8 7:31:18 PM

的主題:4,時間:2.0351562,開始:2014/2/8 7:32:13,結束:2014/2/8 7:32:15

線程:4,時間:2.0527343,開始: 2014年2月8日下午7時32分13秒,結束:2014年2月8日下午7點32分15秒

線程:4,時間:2.0869141,開始:2014年2月8日下午7時32分13秒,結束於2014年2月8日7:32:15

線程:4,時間:2.0898437,開始時間:2014/2/8 7:32:13 PM結束時間:2014/2/8 7:32 :15 PM

線程:8,時間:3.34375,啓動:2014年2月8日下午7時33分13秒,結束:2014年2月8日下午7點33分17秒

線程:8,時間:3.381836,開始:2014/2/8 7:33:13,結束:2014/2/8 7:33:17

線程:8,時間:3.3066406,開始:2014年2月8日下午7時33分14秒,結束:2014年2月8日下午7點33分17秒

線程:8,時間:3.2451172,開始:2014年2月8日7時33分14秒PM,結束:2014年2月8日下午7點33分17秒

線程:8,時間:3.4560547,啓動:2014年2月8日下午7點33分13秒,結束:2014年2月8日7: 33:17 PM

線程:8,時間:3.5029296,開始日期:2014/2/8 7:33:13,結束日期:2014/2/8 7:33:17 PM

線程:8,時間:3.2841796,啓動:2014年2月8日下午7點33分十四秒,結束:2014年2月8日下午7點33分17秒

線程:8,時間:3.4160157,開始:2014年2月8日下午7時33分14秒,結束:2014年2月8日下午7點33分17秒

主題:16,時間:5.9921875,開始:2014年2月8日七時34分14秒下午,結束:2014年2月8日下午7時34分20秒

主題:16,時間:6.4404297,開始:2014年2月8日下午7時34分14秒,結束:2014年2月8日7: 34:20 PM

線程:16,時間:5.3896484,開始日期:2014/2/8 7:34:15 PM結束日期:2014/2/8 7:34:20 PM

主題:16,時間:5.9658203,開始:2014年2月8日下午7點34分十四秒,結束:2014年2月8日下午7時34分20秒

主題:16,時間:5.9873047,開始:2014年2月8日下午7時34分14秒,結束:2014年2月8日下午7點34分20秒

主題:16,時間:6.2226563,開始:2014年2月8日7:34: 14 PM,結束日期:2014/2/8 7:34:20 PM

線程:16,時間:6。1552735,開始:2014/2/8 7:34:14,結束:2014/2/8 7:34:20

線程:16,時間:6.5576172,開始時間:2014/2/8 7: 34:14 PM,結束日期:2014/2/8 7:34:20

線程:16,時間:6.5273437,開始日期:2014/2/8 7:34:14 PM,結束日期:2/8/2014下午7點34分20秒

主題:16,時間:6.2529297,開始:2014年2月8日下午七點34分14秒,結束:2014年2月8日下午7點34分20秒

線程:16,時間:6.2958984,開始日期:2014/2/8 7:34:14,結束日期:2014/2/8 7:34:20

線程:16,時間:5.8544922,開始:2014/2/8 7:34:15,結束:2014/2/8 7:34:20

線程:16,時間:6.3886719,開始: 2/8/2014 7:34:14 PM結束:2014/2/8 7:34:20 PM

線程:16,時間:5.7089844,開始日期:2014/2/8 7:34:15 PM ,結束日期:2014/2/8 7:34:20

線程:16,時間:6.7207031,開始日期:2014/2/8 7:34:14結束時間:2014/2/8 7:34 :20 PM

線程:16,時間:6.0742188,啓動:2014年2月8日下午7點34分14秒,結束:2014年2月8日下午7點34分21秒

請注意,我正在4核Windows 7虛擬機上運行程序。

對我來說沒什麼意義的是,當我有4個線程同時運行時,每個線程比計算1或2個線程時花費的時間少。

有人可以在這裏解釋嗎?

回答

1

操作系統爲您的每個線程提供一定的CPU運行時間。每個線程必須在隊列中等待才能執行,隨着線程數量的增加,此等待時間會變得更長。另一方面,每個線程將獲得更少的執行時間。這在虛擬多核環境中會更明顯,因爲沒有足夠的物理內核來同時執行線程。另外,您應該考慮線程之間的上下文切換具有隨着線程數量增加而增加的成本。因此,請避免在沒有使用的情況下在應用程序上運行多個線程

3

這可能是因爲優化程序沒有真正實現它,直到你到達那裏。嘗試添加一些調用,首先將它調整到程序的開頭,以獲得更一致的結果。我只有一個雙核心,所以我得到了與你展示的結果截然不同的結果,所以我不能更精確。

for (int r = 0; r < 20; r++) 
     fib(40); 
2

這是一個複雜的分析。如前所述,CPU爲每個處理器提供時間片,而且您將受JIT進行優化,但更有可能在4個線程中,CPU能夠以最佳速率平衡時間片和線程上下文切換。我敢肯定,由於許多事情不受你們的控制,這些結果會因每臺機器而大幅變化。