簡體   English   中英

我應該創建多少個線程?

[英]How many threads should I create?

基於這個問題,我有一個類,其中的構造函數僅執行一些賦值,然后有一個build()成員函數實際上可以完成工作。

我知道我將要構建的對象數在[2,16]范圍內。 實際數字是用戶參數。

我在這樣的for循環中創建對象

for (int i = 0; i < n; ++i) {
  roots.push_back(RKD<DivisionSpace>(...));
}

然后在另一個for循環中創建線程。 每個線程都根據以下邏輯在對象塊中調用build()

如果您的向量具有n個元素並且您具有p個線程,則線程i僅寫入元素

[in / 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是我要創建的對象數, Pstd :: thread :: hardware_concurrency的返回值。 處理了C ++ 11功能所遇到的一些問題之后,我讀到以下內容:

即使實現了hardware_concurrency,也不能將其作為對內核數的直接映射。 這就是標准說的返回的內容-硬件線程上下文的數量。 然后繼續說明-該值僅應視為提示。如果您的計算機啟用了超線程,則返回的值很可能是內核數的2倍。 如果您想要一個可靠的答案,則需要使用操作系統提供的所有功能。 – Praetorian

這意味着我可能應該更改方法,因為該代碼是要由多個用戶執行的(並且我的意思是不僅在我的系統中,許多人都將運行該代碼)。 因此,我想以一種既標准又有效的方式選擇線程數。 由於對象的數量相對較少,是否有一些規則可以遵循?

只需選擇一個hardware_concurrency線程池,並以先到先得的原則將項目排隊。

如果系統中的其他進程以某種方式從OS獲得優先級,那就這樣吧。 這僅意味着可以同時運行少於分配的池大小(例如P - 1 )。 沒關系,因為第一個可用的池線程已完成build()將一個項目作為對象將從隊列中選擇下一個項目。

為了真正避免線程在同一核心上競爭,您可以

  • 使用信號量(進程間信號量,如果您要實際協調來自單獨進程的構建器線程)

  • 線程相似性(防止操作系統在下一個時間片將特定線程調度到其他內核上); 遺憾的是,我認為尚無標准的 ,獨立於平台的方式來設置線程相似性。

我沒有令人信服的理由將其變得更復雜

暫無
暫無

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

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