基於this問題,我有一個類,其構造函數只做一些分配,然後有一個實際完成這項工作的成員函數。我應該創建多少個線程?
我知道我將要構建的對象數量在[2,16]的範圍內。實際的數字是一個用戶參數。
我在創造我的對象for循環這樣
for (int i = 0; i < n; ++i) {
roots.push_back(RKD<DivisionSpace>(...));
}
然後在另一個for循環創建線程。每個線程對象的一大塊叫build()
,基於這樣的邏輯:
如果矢量有n個元素,你有P個線程, 線程我只寫元素
[中/ P,( i + 1)n/p)。
因此,舉例來說,情況是這樣的:
std::vector<RKD<Foo>> foos;
// here is a for loop that pushes back 'n' objects to foos
// thread A // thread B // thread C
foos[0].build(); foos[n/3 + 0].build(); foos[2 * n/3 + 0].build();
foos[1].build(); foos[n/3 + 1].build(); foos[2 * n/3 + 1].build();
foos[2].build(); foos[n/3 + 2].build(); foos[2 * n/3 + 2].build();
... ... ...
我遵循的方法是確定的線程p
這樣的數字:
p = min(n, P)
其中n
是我想要創建的對象的數量,並且P
的返回值爲std::thread::hardware_concurrency。 dealing與C++ 11的功能有一些問題後,我讀了這一點:
即使hardware_concurrency實現,它不能依賴作爲直接映射到內核的數量。這是標準所說的返回值 - 硬件線程上下文的數量。並繼續說明 - 只應將此值視爲提示如果您的計算機啓用了超線程,則返回的值完全有可能是內核數量的兩倍。如果你想得到可靠的答案,你需要使用你的操作系統提供的任何設施。 - Praetorian
這意味着我應該改變方法,因爲這個代碼是要從幾個用戶執行(我的意思是不僅在我的系統中,許多人將運行該代碼)。所以,我想以一種既標準又高效的方式選擇線程的數量。由於對象的數量相對較少,是否有一些規則可以遵循或什麼?
我不認爲你所提供的報價意味着你需要改變的方法;它只是說這個值可能是* logical *(或* virtual *)內核的數量,這很好 - 如果它啓用,您就希望利用超線程。如果您的處理器可以並行運行兩倍,那麼使用一半的線程沒有意義。 – bogdan
@bogdan如果你能回答分析你的觀點,那會很棒,因爲現在對我來說還不太清楚:/ – gsamaras
OpenMP定義了[一些環境變量](https://gcc.gnu.org/onlinedocs /libgomp/Environment-Variables.html),它可以用來選擇它將創建的最大線程數。你可以讓你的應用程序檢查具有相似名稱的變量,如果它們不是由用戶設置的,則回退到'std :: thread :: hardware_concurrency'。這就是我可能會做的。 – 5gon12eder