基于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