Я прошу это попытаться понять, что я потратил 24 часа, пытаясь исправить.Matlab ограничивает TBB, но не OpenMP
Моя система: Ubuntu 12.04.2, Matlab R2011a, оба из них 64-разрядный процессор Intel Xeon на основе Nehalem.
Проблема заключается в том, что Matlab позволяет программам на основе OpenMP использовать все ядра ЦП с поддержкой гиперпотока, но не допускает то же самое для TBB.
При запуске TBB я могу запускать только 4 потока, даже когда я изменяю maxNumCompThreads на 8. В OpenMP я могу использовать все потоки, которые я хочу. Без Hyper-threading, как TBB, так и OpenMP используют все 4 ядра, конечно.
Я понимаю, что Hyper-threading и что его виртуальный, но ограничение matlab делает, на самом деле вызывает штраф за производительность (дополнительный reference).
Я проверил эту проблему с помощью 2 программы, простой цикл с
#pragma omp parallel for
и другой очень простой цикл на основе кода TBB образца.
tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred);
tbb::parallel_for_each(tasks.begin(),tasks.end(),invoker<mytask>());
и завернутый в оба из них с помощью matlab mexFunction.
У кого-нибудь есть объяснение? Есть ли неотъемлемая разница в методе или структуре создания потоков, которая позволяет Matlab дросселировать TBB, но не позволяет использовать эту функцию для OpenMP?
Код для ссылки:
OpenMP:
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
threadCount = 100000;
#pragma omp parallel for
for(int globalId = 0; globalId < threadCount ; globalId++)
{
for(long i=0;i<1000000000L;++i) {} // Deliberately run slow
}
}
TBB:
#include "tbb/parallel_for_each.h"
#include "tbb/task_scheduler_init.h"
#include <iostream>
#include <vector>
#include "mex.h"
struct mytask {
mytask(size_t n)
:_n(n)
{}
void operator()() {
for (long i=0;i<1000000000L;++i) {} // Deliberately run slow
std::cerr << "[" << _n << "]";
}
size_t _n;
};
template <typename T> struct invoker {
void operator()(T& it) const {it();}
};
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const
mxArray* prhs[]) {
tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); // Automatic number of threads
std::vector<mytask> tasks;
for (int i=0;i<10000;++i)
tasks.push_back(mytask(i));
tbb::parallel_for_each(tasks.begin(),tasks.end(),invoker<mytask>());
}
Попробуйте инициализировать 'tbb :: task_scheduler_init' с помощью' 8' вместо использования 'offferred'. –
попытайтесь явно контролировать количество потоков: 'maxNumCompThreads' в MATLAB,' omp_set_num_threads' или переменную среды 'OMP_NUM_THREADS' для OpenMP и [эквивалент] (http://stackoverflow.com/q/3786408/97160) для TBB – Amro
Я пробовал оба ваши предложения, не работал. – omarzouk