簡體   English   中英

多線程不比單線程快(簡單循環測試)

[英]Multithreading not faster than single thread (simple loop test)

我正在嘗試一些多線程構造,但不知何故,似乎多線程並不比單個線程快。 我把它縮小到一個非常簡單的測試,使用嵌套循環(1000x1000),系統只計算。
下面我發布了單線程和多線程的代碼以及它們的執行方式。
結果是單個線程在大約110毫秒內完成循環,而兩個線程也需要大約112毫秒
我不認為問題是多線程的開銷。 如果我只將兩個Runnable中的一個提交給ThreadPoolExecutor,它會在單個線程的一半時間內執行,這是有道理的。 但是添加第二個Runnable會讓它慢10倍。 兩個3.00Ghz核心都運行100%。
我認為它可能是特定於PC的,因為其他人的PC在多線程上顯示了雙倍速度的結果。 但那么,我能做些什么呢? 我有一台Intel Pentium 4 3.00GHz(2個CPU)和Java jre6。

測試代碼:

// Single thread:
long start = System.nanoTime(); // Start timer
final int[] i = new int[1];     // This is to keep the test fair (see below)
int i = 0;
for(int x=0; x<10000; x++)
{
    for(int y=0; y<10000; y++)
    {
        i++; // Just counting...
    }
}
int i0[0] = i;
long end = System.nanoTime();   // Stop timer

此代碼在大約110毫秒內執行。

// Two threads:

start = System.nanoTime(); // Start timer

// Two of the same kind of variables to count with as in the single thread.
final int[] i1 = new int [1];
final int[] i2 = new int [1];

// First partial task (0-5000)
Thread t1 = new Thread() {
    @Override
    public void run() 
    {
        int i = 0;
        for(int x=0; x<5000; x++)
            for(int y=0; y<10000; y++)
                i++;
        i1[0] = i;
    }
};

// Second partial task (5000-10000)  
Thread t2 = new Thread() {
    @Override
    public void run() 
    {
        int i = 0;
        for(int x=5000; x<10000; x++)
            for(int y=0; y<10000; y++)
                i++;
        int i2[0] = i;
    }
};

// Start threads
t1.start();
t2.start();

// Wait for completion
try{
    t1.join();
    t2.join();
}catch(Exception e){
    e.printStackTrace();
}

end = System.nanoTime(); // Stop timer

該代碼在大約112毫秒內執行。

編輯:我將Runnables更改為Threads並擺脫了ExecutorService(為了簡化問題)。

編輯:嘗試了一些建議

你肯定不想繼續輪詢Thread.isAlive() - 這沒有充分的理由會燒掉很多CPU周期。 請改用Thread.join()

此外,讓線程直接遞增結果數組,緩存行和所有內容可能不是一個好主意。 更新局部變量,並在計算完成后執行單個存儲。

編輯:

完全忽略了你正在使用奔騰4.據我所知,沒有多核版本的P4 - 為了給出多核的幻覺,它有超線程 :兩個邏輯核共享一個物理執行單元 核心 如果您的線程依賴於相同的執行單元,那么您的性能將與(或更差!)單線程性能相同。 例如,您需要在一個線程中進行浮點計算,在另一個線程中進行整數計算以獲得性能改進。

P4 HT實現受到了很多批評,較新的實現(最近的core2)應該更好。

嘗試稍微增加數組的大小。 不完全是。

在同一線程中順序分配的小對象將傾向於最初順序分配。 這可能在同一個緩存行中。 如果你有兩個內核訪問相同的緩存行(然后micro-benhcmark實際上只是對同一地址執行一系列寫入),那么他們將不得不爭取訪問。

java.util.concurrent中有一個類,它有一堆未使用的long字段。 它們的目的是將不同線程經常使用的對象分成不同的高速緩存行。

我對這種差異並不感到驚訝。 您正在使用Java的並發框架來創建線程(盡管我沒有看到任何保證甚至創建了兩個線程,因為第一個作業可能在第二個作業完成之前完成。

在幕后可能會進行各種各樣的鎖定和同步,而您實際上並不需要進行簡單的測試。 總之認為這個問題是多線程的開銷。

你沒有對i做任何事情,所以你的循環可能只是優化了。

您是否使用Runtime.getRuntime()。availableProcessors()檢查了PC上的可用內核數量?

您的代碼只是增加一個變量 - 無論如何這是一個非常快速的操作。 你在這里使用多個線程並沒有獲得太多收益。 當線程1必須等待某些外部響應或執行一些更復雜的計算時,性能增益更加明顯,同時主線程或其他線程可以繼續處理並且不會等待。 如果您計算更高或使用更多線程(可能是一個安全數字是您機器中的CPU /核心數),您可能會獲得更多收益。

暫無
暫無

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

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