I'm trying to build a task tree then execute it (in the context of game development). Composite tasks can run either in parallel on sequentially. However, I'm running into an assert:
Assertion child->prefix().owner==this failed on line 2173 of file ../../src/tbb/ task.cpp
Does this mean I shouldn't have allocated the task tree before launching the root task? Are there any ways to keep tasks around for multiple execution without having to recycle the whole thing repeatedly? How else should I implement my task tree using TBB? Keep my own tasks separate and spawn tbb::task objects dynamically as I traverse this other tree?
First of all, you are trying to do one thing that is most probably wrong. One should never pre-allocate tasks. TBB tasks are lightweight objects that should be created on demand during your parallel algorithm execution right before they are spawned. One of the benefits of this recommended approach is that owing to the fact that the memory allocated for tasks is reused inside TBB, the total amount of memory allocations will be orders less than in case of the whole tree pre-allocation. Creating tasks on demand also relieves you from the burden of synchronizing access to the shared preallocated task tree.
On the other hand, TBB provides a set of predefined parallel algorithms that cover the most important scenarios of parallel data processing. And often one of them or their combination can be used instead of manual building task hierarchy. Note that the algorithms have already been fine tuned to optimize workload balance and minimize impact on (or even take advantage of ) cache reusing. I do not even mention that using a ready TBB algorithm is much simpler and reliable that writing and debugging your own implementation.
But to be able to help you picking up the most suitable TBB construct, we need more details about your problem. What is the nature of data structure(s) you need to process, and which dependencies (if any) exist between data and/or processing stages?