Multi-Threaded Fluid Simulation
Multi-Threaded Fluid Simulation
Multi-Threaded Fluid Simulation
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
MULTI-THREADED FLUID SIMULATION FOR GAMES<br />
<strong>Simulation</strong><br />
The code is based on an article and sample code written<br />
by Mick West that was recently posted on Gamasutra. 1,2<br />
Since one of our goals was to produce a modular, reusable<br />
code base, the first thing we did was to convert the<br />
existing sample to C++ and separate the simulation from<br />
the rest of the application, specifically from the rendering.<br />
This separation allows the simulation code to be easily<br />
added to an existing code base and rendering engine.<br />
Next, we extended the code into three dimensions,<br />
which turned out to be a fairly straightforward exercise<br />
because none of the algorithms changed appreciably with<br />
the addition of another dimension. For example, the 2D<br />
diffusion step is solved by applying the diffusion operation<br />
to move values from a cell to its neighbors (Figures 1<br />
and 2). This approach is extended in the 3D case so that<br />
instead of inspecting four neighboring cells we look at six<br />
neighbors (Figures 1 and 3). Other cases used the same<br />
principle cpe as well.<br />
Figure 2. A code sample that shows 2D diffusion.<br />
Figure 3. A code sample that shows 3D diffusion.<br />
Figure 1. Transitioning code from 2D to 3D.<br />
The following two code samples (Figures 2 and 3)<br />
show the code that performs the diffusion operation<br />
for non-border case cells in both the 2D and 3D cases.<br />
The border cells are those cells at the very edge of the<br />
grid that are missing one or more neighbors. These cells<br />
are handled separately as special cases. The transition<br />
to 3D is accomplished by adding in consideration for the<br />
z-axis. Apart from that, the algorithm remains essentially<br />
the same.<br />
After transitioning the simulation into 3D, we began<br />
investigating how to break the work up for parallel<br />
processing. As a base for our multi-core work we used<br />
the Intel® Threading Building Blocks (TBB) package. We<br />
found TBB to be very competitive in performance with<br />
other threading APIs. Additionally, it has a lot of built-in<br />
functionality and structures, such as a thread pool, task<br />
manager, and multi-threaded memory management.<br />
The idea behind threading the simulation is data<br />
decomposition: take the grid and break it into smaller<br />
portions. These smaller portions are submitted as tasks<br />
to the task queue and processed by the worker threads,<br />
independently of each other. The grid is broken up evenly<br />
until a small-enough granularity is reached, at which point<br />
further reductions become ineffective, or worse, inefficient<br />
due to thread management overhead. Figure 4 shows an<br />
example of how a 2D grid is broken into four tasks.<br />
1<br />
West, Mick. “Practical <strong>Fluid</strong> Dynamics: Part 1” Gamasutra, 26 June 2008. http://www.gamasutra.com/view/feature/1549/practical_fluid_dynamics_part_1.php<br />
2<br />
West, Mick. “Practical <strong>Fluid</strong> Dynamics: Part 2” Gamasutra, 23 July 2008. http://www.gamasutra.com/view/feature/1615/practical_fluid_dynamics__part_ii.php<br />
2