簡體   English   中英

為什么線程會減慢程序的執行速度?

[英]Why are threads slowing down the execution of my program?

我有一些可以利用並行性提高效率的代碼。 由於我的PC具有雙處理器,因此我嘗試在兩個線程上運行代碼。 所以我寫了下面的代碼(這是它的非常簡化的版本):

Evaluator::evaluate(vector<inpType> input, bool parallel) {
    std::thread t0;
    if(parallel) {
        // Evaluate half of the input in a spawned thread
        t0 = std::thread(&Evaluator::evaluatePart, this, std::ref(input), 0, input.size()/2 + input.size()%2);
        // Evaluate the other half of the input in this thread
        evaluatePart(input, input.size()/2 + input.size()%2 - 1, input.size()/2);
    } else {
        // sequential evaluate all of the input
        evaluatePart(input, 0, input.size());
    }
    // some other code

    // after finishing everything join the thread
    if(parallel) t0.join();
}

Evaluator::evaluatePart(vector<inpType> &input, int start, int count) {
    for(int i=start; i<count; i++) {
        evaluateSingle(input[i]);
    }
}

Evaluator::evaluateSingle(inpType &input) {
    // do stuff with input
    // note I use a vector<int> belonging to Evaluator object in here, not sure it matters though
}

順序運行大約需要3毫秒,而並行運行大約需要6毫秒。 這是否意味着產生一個線程會花費大量時間,以至於僅順序進行評估會更有效率? 還是我做錯了什么?

請注意,我沒有使用任何鎖定機制,因為評估彼此獨立。 每個validateSingle均從作為Evaluator對象成員的向量中讀取,但僅更改為其提供的單個輸入。 因此,不需要任何鎖定。

更新資料

抱歉,我沒有說清楚。 這更多是偽代碼,抽象地描述了我的代碼的樣子。 它不會工作或編譯,但是我的卻不是,這不是問題。 無論如何,我在這段代碼中解決了t0范圍問題。

另外,輸入大小約為38,000,我認為足以使用並行性。

更新資料

我嘗試將輸入大小增加到5,000,000,但這沒有幫助。 順序仍然比多線程快。

更新資料

我嘗試增加運行線程的數量,同時在它們之間平均分配向量以進行評估,並得到一些有趣的結果:

在此處輸入圖片說明

請注意,我有一個i7-7500U CPU,它可以並行運行4個線程。 這給我留下了兩個問題:

  1. 與2、3相比,為什么創建4個或更多線程開始出現性能提升。
  2. 為什么創建4個以上的線程比4個線程(CPU可以同時運行的最大值)更有效。

“為什么會這樣?” 很容易回答。 假設您有一個走廊,可以同時容納四個人。 您想將所有垃圾一端移動到另一端。 最有效率的人數是4。

如果您有1-3個人,那么您會錯過使用一些走廊空間的機會。 如果您有5個或更多的人,那么這些人中至少有一個基本上總是一直排在另一個人后面。 增加越來越多的人只會阻塞走廊,但不會加快活動速度。

因此,您希望擁有盡可能多的人員而不會造成任何排隊。 為什么要排隊(或出現瓶頸)取決於以下情況。

如果不了解線程的本質,很難說。 診斷系統性能時應考慮的一些事項:

是進程/線程

  1. CPU限制(需要大量的CPU資源)
  2. 內存限制(需要大量RAM資源)
  3. 綁定了I / O(網絡和/或硬盤資源)

這三種資源都是有限的,任何一種資源都可能限制系統的性能。 您需要查看您的特定情況正在消耗哪種(可能是2或3)。

您可以使用ntopiostat以及vmstat來診斷正在發生的事情。

編輯1:

我嘗試將輸入大小增加到5,000,000,但這沒有幫助。 順序仍然比多線程快。

順序版本速度更快,因為示例中每次迭代所花費的時間可能非常小,並且創建和管理多個線程會涉及相當大的開銷。

並行編程僅在每次迭代的處理器時間足夠昂貴時才提高效率。

要實際看到差異,請嘗試增加此功能的工作量。

Evaluator::evaluateSingle(inpType &input) {
    // do stuff with input
    // note I use a vector<int> belonging to Evaluator object in here, not sure it matters though
}

編輯2:

  1. 與2、3相比,為什么創建4個或更多線程開始出現性能提升。
  2. 為什么創建4個以上的線程比4個線程(CPU可以同時運行的最大值)更有效。

常見的建議是n + 1線程, n是可用的CPU內核數。 這樣, n線程可以在1個線程等待磁盤I / O時使CPU工作。 線程較少將無法充分利用CPU資源(在某些時候總會有I / O等待),線程過多將導致線程爭用CPU資源。 此外,您還可以參考此答案該答案說明了為什么更多線程是有益的。

暫無
暫無

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

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