我正在尝试在具有 160 个并行线程(8 个 Intel E7-8870)和 0.5 TBytes 内存的机器上使用 tbb::parallel_for。它是当前的 Ubuntu 系统,内核为 3.2.0-35-generic #55-Ubuntu SMP。TBB 来自软件包 libtbb2 版本 4.0+r233-1
即使是非常简单的任务,我也倾向于用完资源,要么是“bad_alloc”,要么是“thread_monitor Resource暂时不可用”。我把它归结为这个非常简单的测试:
#include <vector>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include "tbb/tbb.h"
#include "tbb/task_scheduler_init.h"
using namespace tbb;
class Worker
{
std::vector<double>& dst;
public:
Worker(std::vector<double>& dst)
: dst(dst)
{}
void operator()(const blocked_range<size_t>& r ) const
{
for (size_t i=r.begin(); i!=r.end(); ++i)
dst[i] = std::sin(i);
}
};
int main(int argc, char** argv)
{
unsigned int n = 10000000;
unsigned int p = task_scheduler_init::default_num_threads();
std::cout << "Vector length: " << n << std::endl
<< "Processes : " << p << std::endl;
const size_t grain_size = n/p;
std::vector<double> src(n);
std::cerr << "Starting loop" << std::endl;
parallel_for(blocked_range<size_t>(0, n, grain_size), RandWorker(src));
std::cerr << "Loop finished" << std::endl;
}
典型输出是
Vector length: 10000000
Processes : 160
Starting loop
thread_monitor Resource temporarily unavailable
thread_monitor Resource temporarily unavailable
thread_monitor Resource temporarily unavailable
这些错误是随机出现的,并且随着 n 的增大而出现的频率更高。这里 1000 万的价值是它们经常发生的点。尽管如此,考虑到机器的特性,这应该不会耗尽内存(我单独使用它来进行这些测试)。
粒度是在 tbb 创建太多 Worker 实例后引入的,这使得它在更小的 n 时失败。
谁能建议如何设置 tbb 来处理大量线程?