Я пытаюсь придумать эквивалентную замену циклу Intel TBB parallel_for
, который использует tbb::blocked_range
с использованием OpenMP. Копаясь в Интернете, мне удалось найти упоминание только об одном человеке, который делал что-то подобное; патч, отправленный в проект Open Cascade, в котором цикл TBB выглядел так (но не использовал tbb::blocked_range):
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
и эквивалент OpenMP был:
int i, n = aFaces.size();
#pragma omp parallel for private(i)
for (i = 0; i < n; ++i)
Process (aFaces[i]);
Вот цикл TBB, который я пытаюсь заменить:
tbb::parallel_for( tbb::blocked_range<size_t>( 0, targetList.size() ), DoStuff( targetList, data, vec, ptr ) );
Он использует класс DoStuff
для выполнения работы:
class DoStuff
{
private:
List& targetList;
Data* data;
vector<things>& vec;
Worker* ptr;
public:
DoIdentifyTargets( List& pass_targetList,
Data* pass_data,
vector<things>& pass_vec,
Worker* pass_worker)
: targetList(pass_targetList), data(pass_data), vecs(pass_vec), ptr(pass_worker)
{
}
void operator() ( const tbb::blocked_range<size_t> range ) const
{
for ( size_t idx = range.begin(); idx != range.end(); ++idx )
{
ptr->PerformWork(&targetList[idx], data->getData(), &Vec);
}
}
};
Насколько я понимаю, на основании этой ссылки, TBB разделит заблокированный диапазон на более мелкие подмножества и дать каждому потоку один из диапазонов для циклического прохождения. Поскольку каждый поток получит свой собственный класс DoStuff
, который имеет кучу ссылок и указателей, это означает, что потоки, по сути, совместно используют эти ресурсы.
Вот что я придумал в качестве эквивалентной замены в OpenMP:
int index = 0;
#pragma omp parallel for private(index)
for (index = 0; index < targetList.size(); ++index)
{
ptr->PerformWork(&targetList[index], data->getData(), &Vec);
}
Из-за обстоятельств, не зависящих от меня (это всего лишь один компонент в гораздо более крупной системе, охватывающей +5 компьютеров), просмотр кода с помощью отладчика, чтобы точно увидеть, что происходит,... маловероятен. Я работаю над удаленной отладкой, но это не очень многообещающе. Все, что я знаю точно, это то, что приведенный выше код OpenMP как-то делает что-то не так, как TBB, и ожидаемые результаты после вызова PerformWork для каждого индекса не получаются.
Учитывая приведенную выше информацию, есть ли у кого-нибудь идеи о том, почему код OpenMP и TBB функционально не эквивалентен?
tbb::blocked_range
работает с обратным диапазоном, аfor
— нет. - person Ben Jackson   schedule 03.01.2014size_t
наint
на самом деле является проблемой, если у вас огромное количество элементов. - person Ben Jackson   schedule 03.01.2014