Game Engine Architecture

(Ben Green) #1

772 14. Runtime Gameplay Foundation Systems


tween game objects even when those objects reside in totally separate memory
spaces or are being processed by diff erent physical CPU cores. Some research
has been done into using a distributed programming language, such as Er-
icsson’s Erlang (htt p://www.erlang.org), to code game object models. Such
languages provide built-in support for parallel processing and message pass-
ing and handle context switching between threads much more effi ciently and
quickly than in a language like C or C++, and their programming idioms help
programmers to never “break the rules” that allow concurrent, distributed,
multiple agent designs to function properly and effi ciently.

14.6.4.2. Interfacing with Concurrent Engine Subsystems
Although sophisticated, concurrent, distributed object models are theoreti-
cally feasible and are an area of extremely interesting research, at present
most game teams do not use them. Instead, most game teams leave the ob-
ject model in a single thread and use an old-fashioned game loop to update
them. They focus their att ention instead on parallelizing many of the lower-
level engine systems upon which the game objects depend. This gives teams
the biggest “bang for their buck,” because low-level engine subsystems tend
to be more performance-critical than the game object model. This is because
low-level subsystems must process huge volumes of data every frame, while
the amount of CPU power used by the game object model is oft en somewhat
smaller. This is an example of the 80-20 rule in action.
Of course, using a single-threaded game object model does not mean that
game programmers can be totally oblivious to parallel programming issues.
The object model must still interact with engine subsystems that are them-
selves running concurrently with the object model. This paradigm shift re-
quires game programmers to avoid certain programming paradigms that may
have served them well in the pre-parallel-processing era and adopt some new
ones in their place.
Probably the most important shift a game programmer must make is to
begin thinking asynchronously. As described in Section 7.6.5, this means that
when a game object requires a time-consuming operation to be performed, it
should avoid calling a blocking function—a function that does its work direct-
ly in the context of the calling thread, thereby blocking that thread until the
work has been completed. Instead, whenever possible, large or expensive jobs
should be requested by calling a non-blocking function—a function that sends
the request to be executed by another thread, core, or processor and then im-
mediately returns control to the calling function. The main game loop can
proceed with other unrelated work, including updating other game objects,
while the original object waits for the results of its request. Later in the same
Free download pdf