我应该创建多少个线程?

时间:2015-01-15 21:48:10

标签: c++ multithreading c++11 theory

根据this问题,我有一个类,其构造函数只执行一些赋值,然后有一个build()成员函数实际完成这项工作。

我知道我必须构建的对象数量在[2,16]的范围内。实际数字是用户参数。

我在像这样的for循环中创建我的对象

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

然后在另一个for循环中创建线程。根据以下逻辑,每个线程在一大块对象中调用build()

  

如果你的矢量有n个元素并且你有p个线程,   线程我只写元素

     

[i n / 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的返回值。在dealing之后出现了C ++ 11特性的一些问题,我读到了这个:

  

即使实现了hardware_concurrency,也不能将其作为直接映射到核心数量。这就是标准所说的返回 - 硬件线程上下文的数量。并继续说明 - 此值应仅被视为提示如果您的机器启用了超线程,则返回的值完全有可能是内核数量的2倍。如果您需要可靠的答案,则需要使用操作系统提供的任何功能。 - Praetorian

这意味着我应该改变方法,因为这个代码意味着要从几个用户执行(我的意思是不仅在我的系统中,很多人都会运行该代码)。所以,我想以一种标准和高效的方式选择线程数。由于对象的数量相对较少,是否有一些规则要遵循?或者什么?

1 个答案:

答案 0 :(得分:2)

只需选择一个hardware_concurrency个主题的线程池,并按照先到先得的原则排列这些项目。

如果系统中的其他进程以某种方式从操作系统获得优先权,那么就这样吧。这仅仅意味着可以同时运行少于分配的池大小(例如P - 1)。自第一个可用的池线程完成build()以来,没有关系 - 一个项目将从队列中选择下一个项目。

要真正避免线程在同一核心上竞争,你可以

  • 使用信号量(如果要实际协调来自不同进程的构建器线程,则为进程间信号量)

  • 线程亲和性(防止OS在下一次切片时将特定线程调度到不同的核心);遗憾的是,我认为没有标准,与平台无关的方式来设置线程关联性(还有)。

我认为没有令人信服的理由让它更复杂