i
i
i
i
i
i
i
i
298 12. Data Structures for Graphics
data in a “nice” arrangement is accomplished by tiling, sometimes also called
bricking. A traditional 2D array is stored as a 1D array together with an indexing
mechanism; for example, an N
x
by N
y
array is stored in a 1D array of length
N
x
N
y
and the 2D index (x, y) (which runs from (0, 0) to (N
x
−1,N
y
−1))maps
to the 1D index (running from 0 to N
x
N
y
− 1) using the formula
Figure 12.40. The mem-
ory layout for an untiled 2D
array with
N
x
=
4
and
N
y
=
3
.
index = x + N
x
y.
An example of how that memory lays out is shown in Figure 12.40. A problem
with this layout is that although two adjacent array elements that are in the same
row are next to each other in memory, two adjacent elements in the same column
will be separated by N
x
elements in memory. This can cause poor memory lo-
cality for large N
x
. The standard solution to this is to use tiles to make memory
locality for rows and columns more equal. An example is shown in Figure 12.41
where 2 × 2 tiles are used. The details of indexing such an array are discussed in
the next section. A more complicated example, with two levels of tiling on a 3D
array, is covered after that.
A key question is what size to make the tiles. In practice, they should be
similar to the memory-unit size on the machine. For example, if we are using
Figure 12.41. The mem-
ory layout for a tiled 2D ar-
ray with
N
x
=
4
and
N
y
=
3
and 2 × 2 tiles. Note that
padding on the top of the
array is needed because
N
y
is not a multiple of the tile
size two.
16-bit (2-byte) data values on a machine with 128-byte cache lines, 8 × 8 tiles fit
exactly in a cache line. However, using 32-bit floating-point numbers, which fit
32 elements to a cache line, 5 × 5 tiles are a bit too small and 6 × 6 tiles are a
bit too large. Because there are also coarser-sized memory units such as pages,
hierarchical tiling with similar logic can be useful.
12.5.1 One-Level Tiling for 2D Arrays
If we assume an N
x
×N
y
array decomposed into square n×n tiles (Figure 12.42),
then the number of tiles required is
B
x
= N
x
/n,
B
y
= N
y
/n.
Here, we assume that n divides N
x
and N
y
exactly. When this is not true, the
array should be padded. For example, if N
x
=15and n =4,thenN
x
should
be changed to 16. To work out a formula for indexing such an array, we first find
the tile indices (b
x
,b
y
) that give the row/column for the tiles (the tiles themselves
form a 2D array):
b
x
= x ÷ n,
b
y
= y ÷ n,