2017-04-05 36 views
3

我試圖運行這個簡單的程序,並想知道爲什麼輸出出錯。代碼查詢硬件併發性,然後嘗試啓動大量線程並執行一些任務。爲了存根任務,我寫已經調整向量的各個元素,但結果仍是未來的錯誤 -根據硬件併發性將任務等分爲線程

#include <iostream> 
#include <thread> 
#include <vector> 
#include <functional> 

void myMethod(std::vector<int> &v, int threadNumber) { 
    for(int i = threadNumber - 1; i < v.size(); i+= threadNumber) { 
     v[i] = threadNumber; 
    } 
} 

int main() { 
    const auto numThread = std::thread::hardware_concurrency(); 
    std::vector<int> vec; 
    vec.resize(100, 0); 

    if(numThread < 2) { 
     std::cout << "Not running\n"; 
     return 0; 
    } 

    std::vector<std::thread> vT; 
    for(int i = 1; i <= numThread; ++i) { 
     vT.emplace_back(myMethod, std::ref(vec), i); 
    } 
    for(auto &t: vT) { t.join(); } 


    for(const auto &i: vec) { 
     std::cout << i << ' '; 
    } 
    std::cout << std::endl; 
} 

輸出當屬 -

1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 1 3 1 4 3 2 1 4 1 2 3 4 

,但我期待 - 1 2 3 4 1 2 3 4 ...

+3

在'myMethod的(...)',你的意思是'我+ =的std ::螺紋:: hardware_concurrency()'? –

+2

實現注意事項:'v'有很多可能的分區,但最自然的兩個分區是這樣的(striping,size = 1),並在大約'v.size()/ numThreads'的numThreads'分區中分隔'v'每。條紋的缺點是'v'的相鄰元素可能會共享一條緩存行,然後這個緩存行將被爭用。通過使用更少,更大的塊,緩存爭用更少,因爲大多數相鄰元素將由同一個CPU內核處理。 – MSalters

+1

@MSalters謝謝你,但我不明白我會如何分裂。如果numThreads是2,它將非常簡單 - 發送正確的一半到第一個線程並休息給其他人,但是隨着numThreads變大並且numTasks變得像100tasks/8threads一樣大,很難像這樣分配給我:/。我的意思是,直到我應該給第一條線和第二條線發送什麼任務......,我很難想象它。我不是CS專業,仍然在學習編程,所以任何幫助都會被推薦。 – buggy3

回答

5

在你myMethod功能,你用錯量增加可變i -

void myMethod(std::vector<int> &v, int threadNumber) { 
    for(int i = threadNumber - 1; i < v.size(); i+= threadNumber) { 
     v[i] = threadNumber; 
    } 
} 

實際上應該是 -

void myMethod(std::vector<int> &v, int threadNumber) { 
    const auto numThread = std::thread::hardware_concurrency(); 
    for(int i = threadNumber - 1; i < v.size(); i+= numThread) { 
     v[i] = threadNumber; 
    } 
}