2012-02-15 3 views
0

Я пытаюсь использовать Intel TBB для параллелизации внутреннего цикла (2 из 3), однако, я получаю приличную компенсацию, когда внутренние 2 цикла имеют значительный размер.Оптимизация внутреннего цикла C++ intel TBB

Является ли TBB новыми нитями для каждой итерации основной петли? Есть ли способ уменьшить накладные расходы?

tbb::task_scheduler_init tbb_init(4); //I have 4 cores 
tbb::blocked_range<size_t> blk_rng(0, crs_.y_sz, crs_.y_sz/4); 
boost::chrono::system_clock::time_point start =boost::chrono::system_clock::now(); 
for(unsigned i=0; i!=5000; ++i) 
{ 
    tbb::parallel_for(blk_rng, 
    [&](const tbb::blocked_range<size_t>& br)->void 
    { 
    ::: 

Возможно, было бы интересно отметить, что openMP (который я пытаюсь удалить !!!) не имеет этой проблемы.

Я компиляции с:

Intel ICC 12,1 при -03 -xHost -mavx

На интел 2500K (4 ядра)

EDIT: Я действительно может изменить порядок петель, потому что тест out loops необходимо заменить предикатом, основанным на результатах циклов.

+0

Похоже, вы просите, чтобы он произвел параллельную работу 5000 раз, это точно? – user7116

+0

@sixlettervariables да, я получаю большие выгоды от openMP, я хочу знать, могу ли я реплицировать такие выигрыши с помощью TBB – 111111

+2

попробуйте использовать разделители в tbb, особенно affinity_partiioner, если вы этого не сделали. Фиксированное разделение OpenMP действительно хорошо подходит для небольших внутренних циклов из-за политик, применяемых к командам потоков ... – Rick

ответ

1

Нет, TBB не создает новые потоки для каждого вызова parallel_for. Фактически, в отличие от параллельных областей OpenMP, каждая из которых может начать новую команду нитей, TBB работает с той же командой потоков, пока все объекты task_scheduler_init не будут уничтожены; и в случае неявной инициализации (при отсутствии task_scheduler_init) одни и те же рабочие потоки используются до конца программы.

Таким образом, проблема с производительностью вызвана чем-то другим. Наиболее вероятные причины, из моего опыта, являются:

  • отсутствия оптимизации компилятора, авто-векторизация быть первым (может быть проверена путем сравнения однопоточной производительности OpenMP и Т, если Т гораздо медленнее, то это является наиболее вероятной причиной).
  • недостаток кэша; если вы 5000 раз пропустили одни и те же данные, местность кеша имеет огромное значение, а значение по умолчанию для OpenMP schedule(static) работает очень хорошо, детерминистически повторяя точно такое же разбиение на разделы каждый раз, в то время как планировщик кражи работы TBB имеет значительную случайность. Установка размера зернистости block_range, равного task_size/num_threads, обеспечивает одну часть работы на поток, но не гарантирует одинаковое распределение частей; и affinity_partitioner должен помочь с этим.
Смежные вопросы