2014-01-25 141 views
0

我做了一個小程序來觀察使用兩個線程的速度。我正在計算填充數組的過程。主線程和線程1調用函數1來解除數組的不同部分。我期望通過使用兩個線程來看到更快的結果。相反,我得到的時間更慢,註釋掉的代碼執行速度更快。我在哪裏錯了?C++線程性能

#include <chrono> 
#include <iostream> 
#include <vector> 
#include <thread> 


void function_1(int I, int J, int *B){ 
    for (int i = I; i<(J+1); i++) { 
     B[i] = 100; 
     //std::cout << B[i] << std::endl; 
    } 
} 

int *count; 

int main(int argc, const char * argv[]) 
{ 
    count = new int[20000]; 

    std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); 
    //function_1(0, 19999, count); 
    std::thread thread1(function_1, 0, 9999, count); 
    thread1.join(); 
    function_1(10000, 19999, count); 

    std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now(); 
    auto time_span = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count(); 
    std::cout << "time taken is :" <<time_span << " ms"<<std::endl; 

    return 0; 
} 

回答

2

你被立即加入線程1創建後馬上同步執行示例代碼。 main()中的執行將阻塞,直到該線程終止處理,然後將移至function_1(10000, 19999, count);爲了利用額外的線程,請嘗試在主要調用function_1(10000, 19999, count);之後移動加入調用。

+0

我搬到了主的號召,function_1後thread1.join()。由於某些原因,使用兩個線程的速度仍然比使用帶有註釋代碼的一個線程慢。 – gumby

+1

測試看起來有點過分。線程管理很可能會對您的性能產​​生負面影響。線程並不是真正的免費並行運行方式。 – 2014-01-25 01:46:34

+1

@Mario:這真的是一小部分工作。您可以嘗試將陣列放大10倍或100倍。 – Blastfurnace

2
std::thread thread1(function_1, 0, 9999, count); 
thread1.join(); 
function_1(10000, 19999, count); 

主線程將等待thread1完成調用function_1前的工作。這是一樣的主線程調用

function_1(...) 
function_1(...) 

,只能使用管理線程所帶來的額外成本。在主線程上調用function_1之後,您可能需要join()

此外,你應該增加的工作量,使測試更加重要。線程並不是真正實現工作快速完成的免費方式。在決定是否與您的情況相關之前,您需要考慮維護線索的成本。

+0

我把主線程的調用移到了thread1實例化和thread1.join()之前的function_1。時間比原來的結果略有改善。但出於某種原因,它不會比使用帶有註釋代碼的一個線程更快。 – gumby

+0

請參閱其他答案或我的修改意見。 – 2014-01-25 01:52:29

0

你不可能看到一個重大的改進,當手頭的任務只由填充內存。

的問題是相當簡單:單核大概能飽和完整帶寬的內存。既然如此,添加更多的線程就無法帶來好處,除非您的計算機具有多個處理器,而不僅僅是一個套接字中的多個內核。

使用多個插座,您可以通過具有獨立的物理處理器上運行,每一個都有自己的連接到存儲不同的線程獲得的速度提升。但是,爲了使其生效,通常需要使用一些非標準函數調用來確保每個線程在單獨的物理處理器上運行,並確保每個處理器上運行的線程都寫入該處理器本地的內存。

那些既不是完全的火箭科學,但他們不一定是微不足道無論是。即使在最簡單的情況下,至少有一小部分代碼幾乎肯定是不可移植的。

要從多個線程中看到主要收益,您通常需要執行包含各種不同類型工作的任務:例如,某些I/O限制,一些限制內存,一些限制處理器。在這種情況下,從多線程獲得大幅提速要容易得多。如果你不能這樣做,那麼處理器受限的東西可能是第二選擇。假設你可以在線程之間很少或者不同步的情況下做到這一點,那麼你可以得到一個大致線性的加速(即N個內核執行代碼大約比一個內核快N倍)的機會是相當不錯的。