如何使用 TBB 获取任务
How to get tasks working with 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;
}
您分配了 'root' 个任务而不是 'child' 个任务。不同之处在于 allocate_root()
创建独立的任务,它不指向任何东西作为它的后继者。因此 wait_for_all()
没有收到相应的任务完成信号,因此挂起。
您可以在 TBB documentation 此处找到正确的原始示例。
或者您可以通过添加 a.
.. 和 b.set_parent(this)
来解决您的问题,这有效地将 allocate_root()
和 allocate_child()
之间的差异修复为 I implemented here.
下面的代码可以编译,但似乎卡在了我使用英特尔 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;
}
您分配了 'root' 个任务而不是 'child' 个任务。不同之处在于 allocate_root()
创建独立的任务,它不指向任何东西作为它的后继者。因此 wait_for_all()
没有收到相应的任务完成信号,因此挂起。
您可以在 TBB documentation 此处找到正确的原始示例。
或者您可以通过添加 a.
.. 和 b.set_parent(this)
来解决您的问题,这有效地将 allocate_root()
和 allocate_child()
之间的差异修复为 I implemented here.