2016-02-18 59 views
1

對於一個分配,我必須實現一個Java程序,當它與多個線程一起運行實際上比只有1時慢。我知道創建線程需要一些開銷,但在本例中我正在處理20,000 x 20,000的大數組。沒有依賴關係,所以創建4個較小的塊並同時運行它們的好處應該始終超出創建線程的成本嗎?什麼時候1個線程的運行速度會比多個線程同時運行的要快

for (int i = 0; i < numThreads; i++) { 

// for each iteration of the body's for loop, 
// calculate the starting and ending indexes 
// of the ith chunk of the y dimension of 
// the anArray array 
final int indexStart = i * chunkSize; 
final int indexEnd = (i + 1) * chunkSize; 

// each "execute" method of the Executor class 
// creates a new object of type Runnable ... 
// be careful with the parentheses here ... the 
// entire next code block is being passes 
// as a parameter to the execute method 
ex.execute(new Runnable() { 

    // The run() method is declared abstract in the Runnable 
    // class, so it MUST be overriden. The body of the 
    // run method is the "code" that each thread executes 
    @Override 
    public void run() { 

     for (int j=0; j<anArray.length; j++){ 
     for (int k = indexStart; k < indexEnd; k++){ 
          anArray[j][k] = anArray[j][k] * anArray[j][k]/3.45 * Math.sqrt(anArray[j][k]); 

         } 

     } // end for 

    } // end run 
    } 
    ); 
} 

我們的任務是修改只有最裏面的循環中,我們可以做什麼都希望我們在那裏,但它有當多個線程執行,使運行速度較慢。具有8個線程的上限。 我真正的問題是在實現多個線程時可能導致更多的問題。我已經做了一些研究,發現你可以使用單線程來使用大多數的CPU,所以創建更多不會幫助,這怎麼可能。

+0

是否有可以創建的線程數的上限?如果沒有,那麼你可以在每次迭代(或其混合)上創建一個線程。 – txtechhelp

+0

應該是一個8的上限 – user3267256

+0

你說'*它必須使運行時運行速度較慢,執行時少線程*'。而你的頭銜似乎相反......你想要什麼? – smwikipedia

回答

2

我已經做了一些研究,發現你可以使用單線程的大部分CPU,所以創建更多不會幫助,這怎麼可能。

多個線程獨立運行時效果最佳。這意味着任何對共享資源的過度使用都會限制甚至使多線程使用速度變慢。

假設你有一個4核的Socket。這意味着你有4個核心,每個核心都有32KB的L1緩存。如果您使用的內存量超過這個數量,則必須使用速度降低3-4倍的L2緩存。但這些只有256 KB的內存。如果您使用的不止於此,則必須使用唯一的一個L3緩存。即使用超過1 MB的內存,並且您的應用程序不再縮放,速度可能會變慢。

在你的情況,你也使用浮點單元esp Math.sqrt,它需要相當多的CPU。每個內核只有一個FPU,所以你很可能會發現使用超線程技術不會有太大幫助。 (或許< 10%)

總之,由於你的浮點運算非常昂貴,我認爲你應該獲得良好的可擴展性,直到你擁有的核心數量。當你獲得更多內核時,你的L3緩存將成爲瓶頸。例如對於18個內核,您可能會發現這是一個問題。

+0

好。我第一次聽說L1,L2,L3緩存。我會探索他們:) –

2

什麼時候1個線程的運行速度會比多個線程同時運行快。

這裏有一些:

  1. 如果您正在創建自己的主題:當所花費的時間來創建和啓動N個線程和運行中號任務,每個比運行n個時間大*單個線程上的M個任務。提示:啓動Java線程非常昂貴。

  2. 如果您在使用Executor計劃任務所花費的時間很大,以執行任務。

  3. 當你有太多的線程相對於核心的數量。提示:多線程(對於計算綁定任務)可以獲得的加速受限於內核數量,而不受線程數量的限制。

  4. 當任務具有固有的併發瓶頸時,如訪問/更新公共同步數據結構。

  5. 當任務涉及跨多個線程訪問大量內存單元,並且會導致大量內存緩存未命中和內存爭用。

  6. 如果您在基準測試中犯了錯誤,例如當你沒有適當考慮「JVM熱身」效應時。


在這種情況下,我認爲多線程比單線程更好,因爲我們有更多的內核。 100螺紋1芯VS 100螺紋4芯。

如果你有4個內核,那麼在這個例子中運行100個線程不會比4個線程提供更多的加速。現在添加一個事實,即您有開始96個線程的開銷,這些開銷並沒有幫助...並且這可以解釋爲什麼多個(100)線程比單個線程的

此外,您的示例可能會產生大量的緩存未命中和內存流量。看起來你將會讀取和寫入4億個元素的數組中的每個單元格。內存爭用成爲瓶頸。

+0

好的總結。我對第3點有一個疑問。在這種情況下,我認爲多線程比單線程更好,因爲我們有更多的內核。 100螺紋1芯VS 100螺紋4芯。 –

相關問題