如何使用TBB完成任务

时间:2015-10-19 17:09:27

标签: c++ tbb

下面的代码编译但似乎卡在我使用英特尔TBB完成的任务中。它只是运行并且不显示任何内容,我必须终止该程序才能结束它。基本上,我在一本书中的一个例子后对此进行了建模,我可能做错了。我对这些任务做错了什么?我正在使用g ++ 4.8.4并认为我正在使用TBB 3.9。

/*
    g++ test0.cpp -o test0.out -std=c++11 -ltbb
*/

#include <iostream>
#include "tbb/task_scheduler_init.h"
#include "tbb/task.h"

using namespace tbb;

long serial_fibo(long n) {
    if(n < 2) {
        return n;
    } else {
        return serial_fibo(n - 1) + serial_fibo(n - 2);
    }
}

class Fibo_Task: public task {
public:
    const long n;
    long* const sum;

    Fibo_Task(long _n_, long* _sum_) :
        n(_n_), sum(_sum_) {}

    // override virtual function task::execute
    task *execute() {
        if(n < 4) {
            *sum = serial_fibo(n);
        } else {
            long x = 0, y = 0;

            // references x
            Fibo_Task& a =
                *new(task::allocate_root())
                    Fibo_Task(n - 1, &x);

            // references y
            Fibo_Task& b =
                *new(task::allocate_root())
                    Fibo_Task(n - 2, &y);

            // two children and another to wait
            set_ref_count(3);
            spawn(a);
            spawn_and_wait_for_all(b);
            *sum = x + y;
        }
        return NULL;
    }
};

long parallel_fibo(long n) {
    long sum;
    Fibo_Task& a =
        *new(task::allocate_root())
            Fibo_Task(n, &sum);

    task::spawn_root_and_wait(a);
    return sum;
}

int main() {
    task_scheduler_init init;

    long number = 8;
    long first = serial_fibo(number);
    long second = parallel_fibo(number);

    std::cout << "first: " << first << "\n";
    std::cout << "second: " << second << "\n";

    return 0;
}

1 个答案:

答案 0 :(得分:1)

您分配了“root”任务而不是“子”任务。不同之处在于allocate_root()创建了独立的任务,并没有指出任何东西作为其后继者。因此wait_for_all()没有收到相应的信号,表明任务已完成并因此挂起。

您可以在TBB documentation中找到正确的原始示例。

或者您可以通过添加a. ..和b.set_parent(this)来解决问题,从而有效地将allocate_root()allocate_child()之间的差异修复为I implemented here