[英]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個線程。 這給我留下了兩個問題:
“為什么會這樣?” 很容易回答。 假設您有一個走廊,可以同時容納四個人。 您想將所有垃圾一端移動到另一端。 最有效率的人數是4。
如果您有1-3個人,那么您會錯過使用一些走廊空間的機會。 如果您有5個或更多的人,那么這些人中至少有一個基本上總是一直排在另一個人后面。 增加越來越多的人只會阻塞走廊,但不會加快活動速度。
因此,您希望擁有盡可能多的人員而不會造成任何排隊。 為什么要排隊(或出現瓶頸)取決於以下情況。
如果不了解線程的本質,很難說。 診斷系統性能時應考慮的一些事項:
是進程/線程
這三種資源都是有限的,任何一種資源都可能限制系統的性能。 您需要查看您的特定情況正在消耗哪種(可能是2或3)。
您可以使用ntop
和iostat
以及vmstat
來診斷正在發生的事情。
我嘗試將輸入大小增加到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、3相比,為什么創建4個或更多線程開始出現性能提升。
- 為什么創建4個以上的線程比4個線程(CPU可以同時運行的最大值)更有效。
常見的建議是n + 1
線程, n
是可用的CPU內核數。 這樣, n
線程可以在1個線程等待磁盤I / O時使CPU工作。 線程較少將無法充分利用CPU資源(在某些時候總會有I / O等待),線程過多將導致線程爭用CPU資源。 此外,您還可以參考此答案 , 該答案說明了為什么更多線程是有益的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.