我试图在具有160个并行线程(8个Intel E7-8870)和0.5 TB内存的机器上使用tbb :: parallel_for。它是当前的Ubuntu系统,内核为3.2.0-35-generic#55-Ubuntu SMP。 TBB来自包libtbb2版本4.0 + r233-1
即使执行一项非常简单的任务,我也会耗尽资源,“bad_alloc”或“thread_monitor资源暂时不可用”。我把它归结为这个非常简单的测试:
#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来处理大量线程吗?
答案 0 :(得分:1)
在答案中总结评论中的讨论:
消息&#34; thread_monitor资源暂时不可用于pthread_create&#34;基本上告诉TBB无法创建足够的线程; &#34;资源暂时不可用&#34;是strerror()
报告pthread_create()
返回的错误代码的内容。此错误的一个可能原因是没有足够的内存来为新线程分配堆栈。默认情况下,TBB为工作线程请求4M堆栈;如果需要,可以使用tbb::task_scheduler_init
构造函数的参数调整此值。
在这个特殊情况下,正如Guido Kanschat报道的那样,问题是由于ulimit
意外设置造成的,这限制了可用于该过程的内存。