簡體   English   中英

當我使用線程時,為什么以下代碼的性能會降低?

[英]Why the performance of following code is degrading when I use threads?

當我使用線程時,為什么以下代碼的性能會降低?

** 1.沒有線程

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]);
    }            
}

您所說的操作已經相當快,在創建線程和啟動並運行所有內容時會產生性能開銷。 很可能你的線程創建,數組拆分和所需的額外計算是構成額外時間的原因。

最可能的原因是您的問題不足以克服啟動線程的固有開銷。 並且,正如您指示您只有2個內核,如果您沒有I / O,則使用4個線程是過度的。 在任何給定時間最多可以運行2個線程,因此只有4個線程才能確保您有一些不必要的上下文切換。

對於大問題,也可能是你可能遇到內存抖動問題。 在這種情況下,這不太可能,但是你已經分解了你的工作,以便每個線程處理不同的內存塊。 這些可以位於不同的頁面上,如果內存是瓶頸,它可能會換出一個線程使用的頁面來引入另一個頁面所需的頁面。 每次切換上下文時,都可能需要執行此頁面交換。 一種更好的方式來構建問題將是讓每個線程i開始對i列,第然后由線程數步行。 這樣,假設線程以大致相同的速率前進,線程的引用位置是相同的,並且它們都在相同的頁面上工作 - 沒有顛簸。

也許你的線程開銷比任何性能節省都要大。 嘗試擴展它(IE,使100000000更大),以查看性能上是否仍有相同類型的差距。

如果你正在做一些CPU密集型的事情,那么擁有多個線程的用途有限,如果你超過了硬件線程的數量(因此Ivan關於超線程的問題)。

如果你有線程寫入文件,或從文件中讀取,那么你會看到差異。

如果你有一個cpu / core,那么一切都以單線程運行,因為只有一個線程可以一次做一些事情。

為什么不嘗試每次都有一個短暫睡眠的測試,模擬等待一些較慢的資源,然后你就可以看到多線程的好處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM