Продолжение задач в Intel TBB

Есть ли что-то похожее на продолжение задач PPL в TBB? Мне известен низкоуровневый метод TBB для ручного выделения tbb::tasks, а также ручного выделения задач продолжения и ручного управления счетчиками ссылок для них:

struct FibContinuation: public task {
    long* const sum;
    long x, y;
    FibContinuation( long* sum_ ) : sum(sum_) {}
    task* execute() {
        *sum = x+y;
        return NULL;
    }
};

struct FibTask: public task {
    const long n;
    long* const sum;
    FibTask( long n_, long* sum_ ) :
        n(n_), sum(sum_)
    {}
    task* execute() {
        if( n<CutOff ) {
            *sum = SerialFib(n);
            return NULL;
        } else {
            // long x, y; This line removed 
            FibContinuation& c = 
                *new( allocate_continuation() ) FibContinuation(sum);
            FibTask& a = *new( c.allocate_child() ) FibTask(n-2,&c.x);
            FibTask& b = *new( c.allocate_child() ) FibTask(n-1,&c.y);
            // Set ref_count to "two children plus one for the wait".
            c.set_ref_count(2);
            spawn( b );
            spawn( a );
        // *sum = x+y; This line removed
            return NULL;
        }
    }
};

Это просто ужасно. Вы должны заранее знать, сколько дочерних задач вы создадите, и вручную установить счетчик ссылок соответствующим образом. Это очень хрупкое кодирование...

Способ указания продолжений в PPL очень прост:

create_task([]()->bool
{
  // compute something then return a bool result
  return true
}).then([](bool aComputedResult)
{
  // do something with aComputedResult
});

Как вы достигаете этого в TBB?


person Ed Rowlett-Barbu    schedule 14.04.2013    source источник
comment
Просто какие-то случайные мысли. Фьючерсы на форсирование имеют then, думаю с 1.53 возможно не все методы реализованы, а в других могут быть какие-то баги. Проверьте документы. У TBB нет ничего подобного, одна вещь, которая близка, - это блок-схема TBB. Вы можете создать схему потока для ваших сообщений, TBB будет распараллеливать везде, где это возможно. Хотя это не так просто, как then, оно также намного мощнее. Наконец, я хочу упомянуть, что TBB ориентирован не на параллелизм на основе задач, а на шаблоны алгоритмов, которые абстрагируют проблемы, связанные с параллельными данными.   -  person Stephan Dollberg    schedule 15.04.2013
comment
@bamboon хм, я подумаю, спасибо за ответ   -  person Ed Rowlett-Barbu    schedule 16.04.2013
comment
Вопрос заключается в сравнении реализаций на двух разных языковых диалектах и ​​жалобах на хрупкость деталей, специфичных для проблемы, присутствующих в одном, а не в другом... Пример TBB может дважды зацикливаться на new-increment-spawn, и теперь хрупкость прошло. Вероятно, есть более эффективный spawn_all() или что-то в этом роде!   -  person mabraham    schedule 23.11.2013


Ответы (2)


Да, есть несколько рекомендуемых стилей продолжения TBB, о которых вы можете прочитать по адресу http://www.threadingbuildingblocks.org/docs/help/reference/task_scheduler/catalog_of_recommended_task_patterns.htm. Однако по дизайну библиотеки TBB ни одна из них не использует конструкции С++ 11, как ваш пример PPL.

Если ваш вопрос действительно «есть ли в TBB интерфейс C++11 для продолжения задачи», то ответ — «нет».

person mabraham    schedule 23.11.2013

Прямо ничего нет, я много лет назад опубликовал пример того, как это сделать с помощью task_group (который находится в tbb) в своем блоге здесь.

Синтаксис похож, но не на 100%, поскольку он был опубликован до того, как появилась задача.

void SimpleContinuation()
{
    auto task1 = run_task([](){ContinueableTask(1);});
    //task 2 depends on task 1
    auto task2 = run_when(task1, [](){ContinueableTask(2);});
    wait_for_all(task1, task2);
}
person Rick    schedule 21.04.2013
comment
Это не отвечает на вопрос, как обстоят дела в ТББ. В TBB нет методов run_task и run_when. - person Anton; 30.04.2014
comment
Извините, я не понял, что эти функции реализованы в вашем блоге поверх группы задач. - person Anton; 30.04.2014