Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Avoid "pauses" in game loop



   I've got an existing game engine that uses TBB

  What I'm trying to work around is that if too many tasks are spawned it hitches. 

Anyway the general layout is like this:

1. main loop: spawns a few tasks using task_group, then calls wait()

2. one of these tasks spawned in the task_group contains a flow graph, the graph is executed. 

3. during the flow graph execution it runs one particular function which happens to spawn most of the heavy weight tasks, there tasks should defiantly *not* cause the main loop to wait for them all to finish. If I use spawn( new(tbb::task::allocate_root()) ) I get some serious hitching, I assume TBB must be waiting for all of these tasks to finish before continuing the main loop, or that they interfere with the flow graph?

  Essentially what I want is for all these tasks I am spawning in #3 to be available, but to be only called *after* more important tasks, and to not block the main loop. Is there some way of doing this in TBB? I've seen a few confusing references in the TBB manual, but attempting to use these patterns seem to crash TBB internally.

I tried using an "empty_task" as the root for these tasks I don't want the main loop to wait on, but this crashes inside of the arena.



0 Kudos
2 Replies

  For example :

 The part on Long, low-priority operation:

 This example is hard to follow, or match to how my code operates.  What is this "low priority Root" on the right hand side? Do I just allocate a meaningless task on program startup and use it as low priority Root?  Does this root need to be waited on? Do I need to create a new root each frame? 

 I guess I can create a "Parent" by putting the entire main loop inside of a single task that never returns?





0 Kudos
New Contributor I

The example linked in post #2 relies on an old version of TBB scheduler. It will not work in the intended way with the current version (and several older versions - it was changed quite some time ago).

You could consider using task::enqueue with low priority instead of spawn for those heavy tasks, if you do not need to wait for them to finish. However, if you keep spawning so many normal-priority tasks that they keep all worker threads busy, the low-priority tasks could starve.

If I understand the task_group behavior correctly, it should not wait for the root spawned in the flow graph, but it is possible that the root gets started anyway (it gets chosen by the scheduler), makes the worker threads busy, and thus prevents execution of the tasks that the group is waiting for.

0 Kudos