Game Development Reference
In-Depth Information
plane might need to resolve movement conflicts between models. Execution order
of tasks in a taskset is not constrained. Models may collide since the taskset can
only rely on the initial positions. A nave tasking implementation would cause
inconsistencies.
Dependencies between individual tasks require a new approach. The task must
be broken into pieces that are guaranteed to be independent of each other. In the
case of the AI example, the plane can be divided into sections. Models moving
toward the interior of the section can be resolved in parallel by processing the
sections as a taskset. After the taskset completes, the set of models that move
across sections can be resolved serially in a single task. Even though there is more
work in the task-based approach, overall running time improves since significant
portions of the AI algorithm run in parallel using otherwise idle cycles.
The key observation from the AI example is that a task-based algorithm that
has more overhead runs significantly faster overall than a more optimal single-
threaded approach. Work performed while the machine would otherwise be idle is
essentially free. The game's performance is gated by the completion of the frame
on the main thread. Therefore, a more complex task-based approach can increase
frame throughput even if it takes more cycles to compute.
17.3 Profiling a Task-Based Game Engine
Using a task-based approach simplifies the problem of scheduling work on machines
with large and varying number of cores. The complexity of enforcing dependen-
cies between tasksets and scheduling optimally is delegated to the tasking system.
However, tasking does create a new class of issues. While these new issues may
seem simple to find, in a full game with many systems it is challenging. I have seen
both these examples occur during the development of AAA games.
17.3.1 Data Dependencies
Assume you have two tasksets; an animation taskset and a rendering taskset. The
rendering taskset depends on the output of the animation taskset, but the rendering
taskset does not specify a dependency to the output of the animation set. The
tasking system may schedule both tasksets to run concurrently leading to incorrect
rendering. A small cut-and-paste error can lead to unpredictable timing issues
manifested as corrupt memory or access violation exceptions.
Sampling-based CPU tools fall flat when trying to diagnose data-dependency
errors. A sampling profiler may happen to catch both the render taskset function
and the animation taskset running concurrently. Most sampling profilers aggregate
samples over small time slices. The render taskset should run right after the ani-
mation taskset, so even correct data dependencies between tasksets will appear to
be violated. Also, many other types of bugs can cause memory corruption. You
Search WWH ::




Custom Search