1

我正在尝试在具有 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 来处理大量线程?

4

1 回答 1

1

在答案的评论中总结讨论:

消息“thread_monitor Resource暂时在pthread_create中不可用”基本上告诉TBB无法创建足够的线程;“资源暂时不可用”是strerror()报告返回的错误代码的内容pthread_create()。此错误的一个可能原因是内存不足,无法为新线程分配堆栈。默认情况下,TBB 为一个工作线程请求 4M 的堆栈;tbb::task_scheduler_init如有必要,可以使用构造函数的参数调整此值。

在这种特殊情况下,正如 Guido Kanschat 报告的那样,问题是由ulimit意外设置导致的,这限制了进程可用的内存。

于 2014-10-03T13:23:01.713 回答