我的應用場景是這樣的:我想評估在四核機器上可以達到的性能增益,以處理相同數量的數據。我有以下兩種配置:想在LINUX上分析多線程問題的想法
i)1-進程:沒有任何線程和處理來自1M..1G的數據的程序,而假定系統僅運行其4核的單核。 ii)4線程 - 進程:4線程(所有線程執行相同操作)但處理25%輸入數據的程序。
在我創建4線程的程序中,我使用了pthread的默認選項(即沒有任何特定的pthread_attr_t)。我相信與1-Process配置相比,4線程配置的性能增益應該接近400%(或者介於350%和400%之間)。
我異型在創建線程的花就像下面這樣的時候:
timer_start(&threadCreationTimer);
pthread_create(&thread0, NULL, fun0, NULL);
pthread_create(&thread1, NULL, fun1, NULL);
pthread_create(&thread2, NULL, fun2, NULL);
pthread_create(&thread3, NULL, fun3, NULL);
threadCreationTime = timer_stop(&threadCreationTimer);
pthread_join(&thread0, NULL);
pthread_join(&thread1, NULL);
pthread_join(&thread2, NULL);
pthread_join(&thread3, NULL);
由於在輸入數據的大小在每個線程的內存需求也可能增加而增加的,那麼加載所有數據提前是絕對不可行的選擇。因此,爲了確保不增加每個線程的內存需求,每個線程以小塊讀取數據,處理它並讀取下一個塊來處理它等等。因此,由線程運行我的函數的代碼的結構是這樣的:
timer_start(&threadTimer[i]);
while(!dataFinished[i])
{
threadTime[i] += timer_stop(&threadTimer[i]);
data_source();
timer_start(&threadTimer[i]);
process();
}
threadTime[i] += timer_stop(&threadTimer[i]);
變量dataFinished[i]
被處理標記true
當它接收和處理所有需要的數據。 Process()
知道何時做:-)
在主函數,我計算由4螺紋構造如以下所花費的時間:
execTime4Thread = max(threadTime[0], threadTime[1], threadTime[2], threadTime[3]) + threadCreationTime
。
和性能增益是通過簡單地
gain = execTime1process/execTime4Thread * 100
版本計算: 在周圍1M小數據大小4M,性能增益通常是良好的(350%至400%之間)。然而,隨着輸入尺寸的增加,性能增益的趨勢呈指數級下降。它一直在下降,直到一些數據大小高達50M左右,然後穩定在200%左右。一旦達到這一點,即使是1GB的數據也幾乎保持穩定。
我的問題是,任何人都可以提出這種行爲的主要原因(即,在開始時性能下降,但以後保持穩定)?
並建議如何解決這個問題?
爲了您的信息,我還調查了threadCreationTime
和threadTime
針對每個線程的行爲,以瞭解發生了什麼。對於1M數據,這些變量的值很小,但隨着數據大小的增加,這兩個變量指數增加(但threadCreationTime
應保持幾乎相同,無論數據大小如何,並且threadTime
應以與正在處理的數據相對應的速率增加)。在持續增加到50M左右之後,threadCreationTime
變得穩定,並且threadTime
(就像性能下降變得穩定)和threadCreationTime
以對應於要處理的數據增加的恆定速率增加(這被認爲是可理解的)。
你認爲增加每個線程,進程優先級的東西或(使用pthread_attr_init
)可以幫助其他參數類型調度的自定義值的堆棧大小?
PS:(即最小的OS運行沒有GUI和網絡的東西),同時運行在Linux下的程序失敗,並根安全模式的結果獲得。
你的CPU的型號是什麼? – Tudor
線程間最有可能交叉污染緩存。你有沒有嘗試改變數據塊的大小?您還應該在測量中加載數據,因爲它可能是瓶頸,即2個內核可能會使內存總線飽和。 (另外,如果你還沒有這樣做,你應該把你的定時器放在不同的高速緩存行上。) – Mats
@Mats:處理器是Intel(R)Core(TM)2 Quad CPU Q9950 @ 2.83GHz。 不,我沒有驗證數據塊的大小。好的,我會嘗試更改數據塊的大小。 但是,我不明白你的意思是什麼緩存線。如何把定時器緩存? – Junaid