TBB 任务分配断言
我正在尝试通过 TBB 任务和延续来遍历树。代码如下。当我运行代码时,它不断中止(经常,但并非总是),并出现以下错误:
文件 ../../src/tbb/custom_scheduler.h 第 334 行断言 t_next->state()==task::allocated 失败 详细说明:如果task::execute()返回任务,则必须将其标记为已分配
什么可能导致这个问题?
template<class NodeVisitor>
void
traverse_tree(NodeVisitor& nv)
{
TreeTraversal<NodeVisitor>& tt = *(new(task::allocate_root()) TreeTraversal<NodeVisitor>(nv));
task::spawn_root_and_wait(tt);
}
template<class NodeVisitor>
class TreeTraversal: public task
{
public:
struct Continuation;
public:
TreeTraversal(NodeVisitor nv_):
nv(nv_) {}
task* execute()
{
nv.pre();
Continuation* c = new(allocate_continuation()) Continuation(nv);
c->set_ref_count(nv.size());
for (size_t i = 0; i < nv.size(); ++i)
{
TreeTraversal& tt = *(new(c->allocate_child()) TreeTraversal(nv.child(i)));
spawn(tt);
}
if (!nv.size())
return c;
return NULL;
}
private:
NodeVisitor nv;
};
template<class NodeVisitor>
class TreeTraversal<NodeVisitor>::Continuation: public task
{
public:
Continuation(NodeVisitor& nv_):
nv(nv_) {}
task* execute() { nv.post(); return NULL; }
private:
NodeVisitor nv;
};
I'm trying to traverse a tree via TBB tasks and continuations. The code is below. When I run the code it keeps aborting (frequently, although not always) with the following error:
Assertion t_next->state()==task::allocated failed on line 334 of file ../../src/tbb/custom_scheduler.h
Detailed description: if task::execute() returns task, it must be marked as allocated
What can be causing this problem?
template<class NodeVisitor>
void
traverse_tree(NodeVisitor& nv)
{
TreeTraversal<NodeVisitor>& tt = *(new(task::allocate_root()) TreeTraversal<NodeVisitor>(nv));
task::spawn_root_and_wait(tt);
}
template<class NodeVisitor>
class TreeTraversal: public task
{
public:
struct Continuation;
public:
TreeTraversal(NodeVisitor nv_):
nv(nv_) {}
task* execute()
{
nv.pre();
Continuation* c = new(allocate_continuation()) Continuation(nv);
c->set_ref_count(nv.size());
for (size_t i = 0; i < nv.size(); ++i)
{
TreeTraversal& tt = *(new(c->allocate_child()) TreeTraversal(nv.child(i)));
spawn(tt);
}
if (!nv.size())
return c;
return NULL;
}
private:
NodeVisitor nv;
};
template<class NodeVisitor>
class TreeTraversal<NodeVisitor>::Continuation: public task
{
public:
Continuation(NodeVisitor& nv_):
nv(nv_) {}
task* execute() { nv.post(); return NULL; }
private:
NodeVisitor nv;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我以前从未见过任务被分配为延续,然后从
execute()
返回。这可能是断言失败的原因(更新:实验表明并非如此,请参阅下面的详细信息)。同时,您可以将
TreeTraversal::execute()
的代码更改为大致如下:更新:下面所示的简化测试在我的双核笔记本电脑上运行良好。这让我假设您的实际代码中可能存在内存损坏,在这种情况下,上面建议的重新洗牌可能只是隐藏问题而不是解决它。
I have never seen before that a task is allocated as a continuation and then returned from
execute()
. That might be the reason of the assertion failure (update: an experiment showed it is not, see details below).Meanwhile, you can change the code of
TreeTraversal::execute()
to be roughly this:Update: a simplified test shown below worked well on my dual-core laptop. That makes me suppose possible memory corruption in your actual code, in which case the re-shuffling suggested above might just hide the issue but not fix it.