私がこれを求めているのは、私が 24 時間かけて修正しようとしたことを理解しようとするためだけです。
私のシステム: Ubuntu 12.04.2、Matlab R2011a、両方とも 64 ビット、Nehalem ベースの Intel Xeon プロセッサ。
問題は単純に、Matlab では OpenMP ベースのプログラムがハイパースレッディングを有効にしたすべての CPU コアを利用できるが、TBB では同じことができないということです。
TBB を実行している場合、maxNumCompThreads を 8 に変更しても、起動できるスレッドは 4 つだけです。一方、OpenMP では必要なすべてのスレッドを使用できます。ハイパースレッディングがなければ、TBB と OpenMP の両方がもちろん 4 つのコアすべてを利用します。
ハイパースレッディングとその仮想を理解していますが、matlab の制限により、実際にはパフォーマンスにペナルティが発生します (追加の参照)。
この問題を 2 つのプログラムを使用してテストしました。単純な for ループです。
#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
}
}
未定:
#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>());
}