2010-03-24 81 views
2

當我使用線程時,爲什麼下面的代碼的性能下降?當我使用線程時,爲什麼下面的代碼的性能下降?

** 1.Without線程

int[] arr = new int[100000000]; //Array elements - [0][1][2][3]---[100000000-1]  
addWithOutThreading(arr); // Time required for this operation - 1.16 sec 

爲addWithOutThreading

 public void addWithOutThreading(int[] arr) 
     { 
      UInt64 result = 0; 
      for (int i = 0; i < 100000000; i++) 
      { 
       result = result + Convert.ToUInt64(arr[i]); 
      } 
      Console.WriteLine("Addition = " + result.ToString()); 
     } 

** 2.採用螺紋

int[] arr = new int[100000000]; 
int part = (100000000/4); 
UInt64 res1 = 0, res2 = 0, res3 = 0, res4 = 0; 

ThreadStart starter1 = delegate 
         { addWithThreading(arr, 0, part, ref res1); }; 
ThreadStart starter2 = delegate 
         { addWithThreading(arr, part, part * 2, ref res2); }; 
ThreadStart starter3 = delegate 
         { addWithThreading(arr, part * 2, part * 3, ref res3); }; 
ThreadStart starter4 = delegate 
         { addWithThreading(arr, part * 3, part * 4, ref res4); }; 

Thread t1 = new Thread(starter1); 
Thread t2 = new Thread(starter2); 
Thread t3 = new Thread(starter3); 
Thread t4 = new Thread(starter4); 

t1.Start(); 
t2.Start(); 
t3.Start(); 
t4.Start(); 
t1.Join(); 
t2.Join(); 
t3.Join(); 
t4.Join(); 

Console.WriteLine("Addition = "+(res1+res2+res3+res4).ToString()); 
// Time required for this operation - 1.30 sec 

定義定義爲addWithThreading

public void addWithThreading(int[] arr,int startIndex, int endIndex,ref UInt64 result) 
{    
    for (int i = startIndex; i < endIndex; i++) 
    { 
     result = result + Convert.ToUInt64(arr[i]); 
    }    
} 
+0

時間有什麼區別? – Steve 2010-03-24 14:18:06

+1

你的機器有多少個處理器?任何超線程?如果你只有一個處理器,你可以期望從多線程處理這個總和會有什麼收益? – 2010-03-24 14:19:16

+0

不支持2核心機器和超線程。 – DotNetBeginner 2010-03-24 14:27:35

回答

0

您的線程開銷可能比任何性能節省更大。嘗試擴大這個(IE,使100000000大),看看是否仍然有相同類型的性能差距。

8

您正在討論的操作已經相當快,在創建線程和讓所有東西運行的過程中都存在性能開銷。更可能的是你的線程創建,數組的拆分以及所需的額外計算都是彌補額外時間的原因。

+0

您也有核心競爭和上下文切換。 – 2010-03-24 14:24:23

+0

可能是虛假共享(緩存行ping-ponging)。 – Audrius 2010-03-24 14:57:18

0

如果你正在做一些CPU密集型的工作,那麼如果你仔細研究硬件線程的數量(因此有關超線程的問題),那麼擁有多個線程的用途就會受到限制。

如果您有線程寫入文件或從文件讀取,那麼您將看到不同。

如果你有一個cpu/core,那麼無論如何一切都會作爲單線程運行,因爲一次只有一個線程可以做某件事。

爲什麼不嘗試每次有瞬間睡眠的測試,模擬等待一些較慢的資源,然後您就可以看到多線程的好處。

3

最可能的原因是您的問題根本不足以克服啓動線程的固有開銷。而且,正如你指出你只有2個內核,如果你沒有I/O,使用4個線程是矯枉過正的。至多2個線程可以在任何給定的時間運行,所以4只能確保你有一些不必要的上下文切換。

對於大問題,還有可能的是您可能會遇到內存抖動問題。在這種情況下,這不太可能,但是您已經將工作分開,以便每個線程處理不同的內存塊。這些可以位於不同的頁面上,如果內存是瓶頸,它可以換出一個線程使用的頁面以引入另一個線程所需的頁面。每次切換上下文時,都可能需要執行此頁面交換。構建這個問題的更好方法是讓每個線程i從第i行開始,然後按行的數量逐行。這樣,假設線程以大致相同的速度進行,線程的參考位置是相同的,並且它們都在相同的頁面上工作 - 不會發生抖動。