Я пытаюсь использовать tbb::parallel_for на машине со 160 параллельными потоками (8 Intel E7-8870) и 0,5 ТБ памяти. Это текущая система 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. Значение в 10 миллионов здесь — это точка, где они случаются довольно регулярно. Тем не менее, учитывая характеристики машины, это далеко не должно исчерпать память (использую для этих тестов только ее).
Размер зерна был введен после того, как tbb создал слишком много экземпляров Worker, что привело к сбою для еще меньшего n.
Кто-нибудь может посоветовать, как настроить tbb для обработки большого количества потоков?
strerror()
по коду ошибки, возвращенномуpthread_create()
. Я бы рекомендовал написать простой тест, который не использует TBB и вообще ничего не делает, а просто создает столько потоков, сколько может. Также попробуйте изменить размер стека (через атрибуты потока). По умолчанию TBB запрашивает стек 4M для каждого потока; может быть, в вашем случае будет достаточно меньшего значения? - person Alexey Kukanov   schedule 14.02.2013