Intel TBB использует task_group для сортировки по битону - PullRequest
2 голосов
/ 23 марта 2011

Я реализую битоническую сортировку с использованием Intel TBB. При использовании метода parallel_invoke все идет хорошо. Но при использовании task_group (без вызова метода wait) выходные данные не сортируются. При использовании task_group, как показано ниже, программа не завершается.

void bitonic_merge(bool up, int array[],int size){
  if(size==1){
      return;
  }
  int m = greatestPowerOfTwoLessThan(size);
  bitonic_compare(up, array, size - m, m);
  g->run(Bitonic_Merge(up, array , m));
  g->run(Bitonic_Merge(up, &array[m],size - m));
  g->wait();
  return;    
}

Может кто-то увидеть, что не так? В чем разница между parallel_invoke и использованием task_group? И что лучше использовать в такой ситуации? parallel_invoke или task_group ? Или я должен использовать какой-то другой метод?

Заранее спасибо

Ответы [ 3 ]

4 голосов
/ 20 апреля 2011

Программа не завершает работу, потому что она заблокирована. Ваш код очень близок к правильному, но проблема в том, что «g» - это глобальный указатель на группу задач и вы выполняете рекурсивную декомпозицию задачи, а это не комбинация, которая хорошо сочетается.

Если вы взломали отладчик, я ожидаю, что вы увидите много потоков в task_group :: wait, ожидающих завершения задач.

Задачи не завершаются, потому что вы разделяете свою группу задач между потоками и задачами, и все они фактически ждут друг друга.

Чтобы исправить это, объявите task_group (или structd_task_group) в стеке внутри функции bitonic_merge, это все равно позволит планировать и выполнять задачи во время вызовов, ожидающих, так же, как при использовании parallel_invoke, но потому что task_group isn ' После завершения всех дочерних задач вызов ожидания будет завершен, и во избежание тупика.

Обратите внимание, что я ответил на похожий вопрос с наклоном производительности на форумах msdn для PPL и помните, что синтаксис и семантика task_group, structured_task_group, parallel_invoke и parallel_for / parallel_for_each согласованы между PPL и TBB ; используйте то, что имеет смысл для вас или вашей платформы.

0 голосов
/ 26 марта 2011

Ожидание целевой группы здесь важно.Без wait () функция вернется до завершения рекурсивных «вызовов», выполненных с помощью task_group :: run (), и, очевидно, это нарушит алгоритм.Параллельный параллелизм действительно применим, и он автоматически ожидает завершения «вызванных» функций, что упрощает его использование.Меня (как разработчика TBB) беспокоит то, что данный фрагмент программы не заканчивается.Это должно работать хорошо, насколько я могу судить.Не могли бы вы предоставить полный источник программы (здесь или на форуме TBB ?)

0 голосов
/ 24 марта 2011

Используйте tbb :: parallel_invoke, если число подзадач постоянное. в противном случае используйте рекурсию и группу задач. Поскольку число подзадач равно 2, параллельный_инвойк удобен и прост в реализации.

Для получения более подробной информации см. Шаблоны проектирования Intel TBB

...