2014-06-16 15 views
3

任務定義:我需要映射一個非常大的陣列。例如,讓我們來看一個findMax()函數。所以任務是儘可能快地完成這個任務(這意味着並行)。叉/加入:最佳的線程數

HW:我有8個內核他們每個人都有2個超級線程

public static void main(String... args) { 
    int maxThreadAmount = Runtime.getRuntime().availableProcessors(); // GET 8 
} 

解決方案#1:只需運行任務分成N個線程。其中N應該是一些最佳數字。

Question#1: Next right:int optimalThreadAmount = maxThreadAmount - 1

解決方案#2:我想通過Fork/Join框架解決這個問題。如果輸入過大,每個任務都會分成兩個並行子任務。所以,我會得到這樣的

    Find Max 
        [array] <---- +1 pending thread 
       /  \ 
       /  \ 
      Find Max  Find Max 
      [1/2 array]  [1/2 array] <-------- +2 pending threads 
      / \  / \ 
     /  \  .. .. 
     Find Max  Find Max 
    [1/4 array] [1/4 array]  <-------- +4 four pending threads 
    /  \  /\ 
    /  \  .. .. 
    Find Max Find Max 
    [1/8 array] [1/8 array] <----------- +8 active threads 

問題2:考慮到與叉/加入算法,我們會得到一堆待處理的線程這將是最佳線程數?

+0

'availableProcessors'調用可能已經考慮到HyperThreading。 – chrylis

+0

@chrylis是的,無論如何谷歌說。但由於某種原因,我得到了'8'數字而不是16個。但不管是否需要,問題仍然相關 –

+0

映射數組實際涉及多少工作?如果你是緩存或內存訪問受限,多線程在這裏沒有幫助。另外,如果您的意思是使用Map,請確保Map實現安全有效地處理併發插入。這可能會導致任何多線程獲益。 –

回答

1

OK,我想你要映射x到,說的sqrt(x)的。你可以同時獲得平方根,並將它們放入相應的數組中。但是,根據sqrt和閱讀/寫作menory所需的時間,您可能會使用兩個線程使您的mem訪問飽和。確保每個併發作業至少運行一個μs或分叉/連接開銷變得過大。

+0

我可以用JHM(或其他微型平臺框架)估計讀/寫內存來計算最佳線程數嗎?我想獲得特定硬件和特定操作的最佳線程數量公式 –

2

線程的最佳數量應圍繞核心機器具有的數量。但是,請記住,當你在兩個子任務分解你的工作量,一個任務應該計算,另一個應該是分叉。這意味着你只在分割時創建一個額外的線程。

大多數分叉/連接算法伴隨着一個順序切斷。當您達到某個條件時(例如,確定最大值爲1000的數組),您切換到順序算法(即逐個檢查元素)。所以,如果我想最佳情況來計算你的問題我會說,此刻你已經分裂了14次,產生了16個線程,然後切換到順序算法。這意味着每個內核都有一個線程正在運行,因此將保持忙碌狀態。 (這個猜測假設你的內核有像超線程這樣的東西,如果沒有的話我會說8個線程)。

此外,不建議硬性化您給出的公式(int optimalThreadAmount = maxThreadAmount - 1),因爲這意味着您認爲該機器無所事事,並且可以使用所有線程。

我的猜測是,使用順序截止的時候,你的最佳性能將圍繞16個線程(在沒有其他進程正在使用你的機器)。你可以爲自己測試,總是最好的方法。你想調查的問題是,當你開始產生大量的線程時,每個線程的開銷將變得明顯。

Ps:使用fork/join的優點是您的代碼將可以根據機器的內核數量進行擴展。更多的內核意味着更多的線程將並行運行。這意味着你的線程調度器可以讓更多的線程工作。

編輯 那麼,有什麼是我應該爲內核的給定數量的使用最好的截止?

那麼,我的猜測會是你實現一個分叉/連接算法。你有一個順序切斷(即,一旦我的輸入數組的大小爲x,停止分叉和連接)。

當您知道在哪個系統上運行算法時,您可以運行基準測試。

對於連續截止xy您運行您的代碼。每次迭代您測量應用您的算法需要多長時間。這樣做,你會看到哪種配置最適合你。

再說,如果你想快速和骯髒的方法,你可以做到以下幾點:與p核心

機,輸入數組的大小爲s

Sequential cutoff = s/8 

不過,我強烈建議如前所述,反對這一點。

+0

非常感謝您的答覆!你可以建議正確的方法不硬線代碼線程數在我的代碼?我的意思是我應該多頻繁地重述這一點以及在哪些方面。你能發表一個小例子嗎? –