Sep 11, 2003 - [1] Bowen Alpern, Larry Carter, Ephraim Feig, and Ted Selker. ... [12] David S. Wise, Jeremy D. Frens, Yuhong Gu, and Gregory A. Alexander.
Improving the Performance of Basic Morton Layout by Array Alignment and Loop Unrolling — Towards a Better Compromise Storage Layout Jeyarajan Thiyagalingam
Olav Beckmann
Paul H. J. Kelly
September 11, 2003 Abstract Hierarchically-blocked non-linear storage layouts, such as the Morton ordering, have been proposed as a compromise between row-major and column-major for two-dimensional arrays. Morton layout offers some spatial locality whether traversed row-wise or column-wise. The goal of this techincal report is to make this an attractive compromise, offering close to the performance of row-major traversal of row-major layout, while avoiding the pathological behaviour of column-major traversal. This techincal report explores how spatial locality of Morton layout depends on the alignment of the array’s base address, and also how unrolling has to be aligned to reduce address calculation overhead. We conclude with extensive experimental results using five common processors and small suite of simple benchmark kernels.
1 Introduction Programming languages that offer support for multi-dimensional arrays generally use one of two linear mappings to translate from multi-dimensional array indices to locations in the machine’s linear address space: row-major or column-major. Traversing an array in the same order as it is laid out in memory leads to excellent spatial locality; however, traversing a row-major array in column-major orde r or vice-versa, can lead to an order-of-magnitude worse performance. A further issue with the basic lexicographic layouts is that the exact size of the array can influence the pattern of cache interference misses, resulting in severe performance degradation for some datasizes. The latter problem can be fixed by carefully padding the size of the lexicographic array, but there is no straightforward method for reliably choosing the right amount of padding. Morton order is a hierarchical, non-linear mapping from array indices to memory locations which has been proposed by several authors as a possible means of overcoming some of the performance problems associated with lexicographic layouts [3, 5, 10, 12]. The key advantages of Morton layout are that the spatial locality of memory references when iterating over a Morton order array is not biased towards either the row-major or the column major traversal order [9] and that the resulting performance tends to be much smoother across problem-sizes than with lexicographic arrays [3]. Storage layout transformations, such as using Morton layout, are always valid. These techniques complement other methods for improving locality of reference in scientific codes, such as tiling, which rely on accurate dependence and aliasing information to determine their validity for a particular loop nest. Previous Work. In our investigation of Morton layout, we have thus far confined our attention to non-tiled codes (in Section 6, we comment on the possible relevance of our results for tiled codes). We have carried out an exhaustive investigation of the effect of poor memory layout and the feasibility of using Morton layout as a compromise between row-major and column-major [8, 9]. Our main conclusions thus far were
It is crucial to consider a full range of problem sizes. The fact that lexicographic layouts can suffer from severe interference problems for certain problem sizes means that it is important to consider a full range of randomly generated problem sizes when evaluating the effectiveness of Morton layout [8]. Morton address calculation: table lookup is a simple and effective solution. Production compilers currently do not support non-linear address calculations for multi-dimensional arrays.
2
Section 2: Background: Morton Storage Layout
Wise et al. [12] investigate the effectiveness of the “dilated arithmetic” approach for performing the address calculation. We have found that a simple table lookup scheme works remarkably well [9].
Effectiveness of Morton layout. We found that Morton layout can be an attractive compromise on machines with large L2 caches, but the overall performance has thus far still been disappointing. However, we also observed that only a relatively small improvement in the performance of codes using Morton layout would be sufficient to make Morton storage layout an attractive compromise between row-major and column-major.
Contributions of this techincal report. In this techincal report, we make two contributions which can significantly improve the effectiveness of the basic Morton scheme and which are both always valid compiler transformations.
Aligning the Base Address of Morton Arrays (Section 3). As stated above, the size of lexicographic arrays often needs to be padded in order to avoid poor performance due to interference misses. In this techincal report, we show that for Morton layout arrays, the alignment of the base address of the array can have a significant impact on the amount of spatial locality available when traversing the array. We show that aligning the base address of Morton arrays to page boundaries can result in significant performance improvements. Unrolling Loops over Morton Arrays (Section 4). Most compilers will unroll regular loops over lexicographic arrays in order to better amortise loop overheads and also possibly achieve better instruction level parallelism within loop bodies. Unfortunately, current compilers cannot unroll loops over Morton arrays effectively due to the rather complicated nature of address calculations: unlike with lexicographic layouts, there is no general straight-forward (linear) way of expressing the relationship between array locations A[i][j] and A[i][j+1] which a compiler could exploit. We show that, provided loops are unrolled in a particular way, it is possible to express these relationships by simple integer increments, and we demonstrate that using this technique can significantly improve the performance of Morton layout, especially on x86 architectures.
Structure of the Remainder of the Technical Report. In Section 2, we give a short introduction to Morton storage layout, including the issue of address calculation in Morton order arrays. In Section 3 we we illustrate that the alignment of the base address of a Morton array can have a significant impact on the amount of spatial locality achieved when traversing the array in both row-major and column-major order. In Section 4 we discuss how loops over Morton order arrays can be effectively unrolled in order to reduce loop overheads and the cost of table lookups. In Section 3.1 we discuss our performance results, and Section 6 concludes.
2 Background: Morton Storage Layout Lexicographic array storage. For an M N two-dimensional array A, a mapping S (i; j) is needed, which gives the memory offset at which array element Ai; j will be stored. Conventional solutions are row-major (for example in C and Pascal) and column-major (as used by Fortran) mappings expressed by (M N ) (M N ) Srm (i; j) = N i + j and Scm (i; j) = i + M j ;
;
respectively. We refer to row-major and column-major as lexicographic, i.e. elements are arranged by the sort order of the two indices (another term is “canonical”). Blocked array storage. Traversing a row-major array in column-major order, or vice -versa, leads to poor performance due to poor spatial locality. An attractive strategy is to choose a storage layout which offers a compromise between row-major and column-major. For example, we could break the M N array into small, P Q row-major subarrays, arranged as a M =P N =Q row-major array. We define the blocked row-major mapping function (this is the 4D layout discussed in [3]) as: (M N ) (i; j) Sbrm ;
=
(P
Q) SrmM P N Q (i (
= ;
=
)
(P;Q)
P j=P) + Srm
= ;
(i%P;
j%Q)
Section 2: Background: Morton Storage Layout
Row−major traversal: one in four accesses hits a new cache line
i
j
3
0
1
2
0
0
1
2
1
4
5
6
2
8
9
10
3
12
13
14
4
32
33
34
11111111 00000000 00000000 3 11111111 16 17 18 19 00000000 11111111 00000000 7 11111111 20 21 22 23 00000000 11111111 24 25 26 27 11 11111111 00000000 00000000 11111111 28 29 30 31 15 11111111 00000000 00000000 11111111 35 48 49 50 51
5
36
37
38
39
52
53
54
6
40
41
42
43
56
57
7
44
45
46
47
60
61
3
4
5
6
i 0
7
j
0 1 2 3
1
2
3
4
00001111 1111 00000000 11111111 0000 0000 1111 0000 1111 0000 1111 0000 16 0 1 1111 4 5 0000 1111 0000 1111 1111 0000 0000 1111 0000 1111 0000 1111 0000 1111 6 7 2 3 1111 18 0000 1111 0000 0000 1111 0000 1111 0000 1111 1111 0000 0000 1111 0000 1111 0000 1111 0000 0000 1111 8 9 1111 12 13 24 0000 1111 0000 1111 0000 1111 11111111 00000000 0000 1111 0000 1111 0000 1111 0000 10 11 1111 14 15 26 0000 1111 0000 00001111 1111 0000 00001111 1111
4
32 33
55
5
58
59
62
63
5
6
7
17 20
21
19 22
23
25 28
29
27
30 31
36
37
48
49
52 53
34
35 38
39
50 51
54 55
6
40
41 44
45
56
57 60 61
7
42 43
47
58
59
46
62 63
(8,8)
S
Column−major traversal: one in four accesses hits a new cache line.
mz
(5,4)
Figure 1: Blocked row-major (“4D”) layout with block-size Figure 2: Morton storage layout for an 8 8 array. Location P = Q = 4. The diagram illustrates that with 16-word cache lines, illustrated by different shadings, the cache hit rate is 75% whether the array is traversed in row-major or columnmajor order.
of element A[5; 4℄ is calculated by interleaving “dilated” representations of 5 and 4 bitwise: D0 (5) = 1000102 , D1 (4) = 0100002 . Smz (5; 4) = D0 (5) j D1 (4) = 1100102 = 5010 .
For example, consider 16-word cache blocks and P = Q = 4, as illustrated in Figure 1. Each block holds a P Q = 16-word subarray. In row-major traversal, the four iterations (0; 0), (0; 1), (0; 2) and (0; 3) access locations on the same block. The remaining 12 locations on this block are not accessed until later iterations of the outer loop. Thus, for a large array, the expected cache hit rate is 75%, since each block has to be loaded four times to satisfy 16 accesses. The same rate results with column-major traversal.
Recursive blocking for memory hierarchies. Modern computer systems rely on a TLB to cache address translations: a typical 64-entry data TLB with 8k pages has an effective span of 64 8 = 512kB. Unfortunately, if a blocked row-major array is traversed in column-major order, only one 4 4 subarray will be used for each page that is accessed. Thus, we find that the blocked row-major layout is still biased towards row-major traversal. We can overcome this by applying the blocking again, recursively. Thus, each 8kB page (1024 doubles) would hold a 8 8 array of subarrays with 4 4 elements each. Most systems have a deep memory hierarchy, with block size, capacity and access time increasing geometrically with depth [1]. Blocking should therefore be applied for each level. Note, however, that this becomes very awkward if larger blocksizes are not whole multiples of the next smaller blocksize.
Bit-interleaving and Morton layout. Assume for the time being that, for an M N array, M Write the array indices i and j as
B (i) = im 1 im B ( j) = jn 1 jn
2 : : : i1 i0 2 :::
j1 j0
and
=
2m , N
= 2n .
4
Section 2: Background: Morton Storage Layout
32B cache line 128B cache line 8kB page
Row-major layout 75% 93.75% 99.9%
Morton layout 50% 75% 96.875%
Column-major layout 0% 0% 0%
Table 1: Theoretical hit rates for row-major traversal of a large array of double words on different levels of memory hierarchy. Possible conflict misses or additional hits due to temporal locality are ignored. This illustrates the compromise nature of Morton layout. respectively. From this point, we restrict our analysis to square arrays (where M = N). Now the lexicographic mappings can be expressed as bit-concatenation (written “k”): (M N ) Srm (i; j) = N i + j = B (i)kB ( j)= in 1 in ;
(M ;N )
Scm
(i; j) = i + M
j= B ( j)kB (i) = jn
2 : : : i1 i0 jn 1 jn 2 : : : j1 j0
1 jn 2 : : : j1 j0 in 1 in 2 : : : i1 i0
If P = 2 p and Q = 2q , the blocked row-major mapping is (M N ) (i; j) Sbrm ;
Q) ScmM P N Q (i j) + SrmP Q (i%P j%Q) B (i) n 1 p kB ( j) m 1 q kB (i) p 1 0 kB ( j) q
=
(
(P
=
(
= ;
=
(
):::
)
;
):::
(
;
(
)
;
(
):::
1):::0
Now, choose P = Q = 2, and apply blocking recursively: (N M ) Smz (i; j) ;
=
in
1 jn 1 in 2 jn 2 : : : i1 j1 i0 j0
This mapping is called the Morton Z-order, and is illustrated in Figure 2. Morton layout can be an unbiased compromise between row-major and column-major. The key property which motivates our study of Morton layout is the following:
Given a cache with any even power-of-two block size, with an array mapped according to the Morton order mapping Smz , the cache hit rate of a row-major traversal is the same as the cache-hit rate of a column-major traversal. This applies given any cache hierarchy with even power-of-two block size at each level. This is illustrated in Figure 2. The cache hit rate for a cache with block size 22k is 1
(1=2k).
For cache blocks of 32 bytes (4 double words, k = 1) this gives a hit rate of 50%. For cache blocks of 128 bytes (16 double words, k = 2) the hit rate is 75% as illustrated earlier. For 8kB pages, the hit rate is 96.875%. In Table 1, we contrast these hit rates with the corresponding theoretical hit rates that would result from row-major and column-major layout. Notice that traversing the same array in column-major order would result in a swap of the row-major and column-major columns, but leave the hit rates for Morton layout unchanged. In Section 3, we show that this desirable property of Morton layout is conditional on choosing a suitable alignment for the base address of the array. Morton-order address calculation using dilated arithmetic or table lookup. Bit-interleaving is too complex to execute at every loop iteration. Wise et al. [12] explore an intriguing alternative: represent each loop control variable i as a “dilated” integer, where the i’s bits are interleaved with zeroes. Define D0 and D1 such that
B (D0 (i)) B (D1 (i))
= =
0in 1 0in 2 0 : : : 0i2 0i1 0i0 in 1 0in 2 0 : : : i2 0i1 0i0 0
and
Now we can express the Morton address mapping as Smz (i; j) = D1 (i) j D0 ( j), where “j” denotes bitwiseor. At each loop iteration we increment the loop control variable; this is fairly straightforward. Let “&” denote (N ;M )
Section 3: Alignment of the Base Address of Morton Arrays
5
bitwise-and. Then:
D0 (i + 1) D1 (i + 1) B (Ones0 ) B (Ones1 )
=
j Ones0 ) + 1) & Ones1 ((D1 (i) j Ones1 ) + 1) & Ones0
=
10101 : : : 01010
=
01010 : : : 10101 .
=
((D0 (i)
where
The dilated arithmetic approach works when the array is accessed using an induction variable which can be incremented using dilated addition. We found that a much simpler scheme often works nearly as well: we simply pre-compute a table for the two mappings D0 (i) and D1 (i). The table accesses are very likely cache hits, as their range is small and they have unit stride.
3 Alignment of the Base Address of Morton Arrays With lexicographic layout, it is often important to pad the row (respectively column) length of an array to avoid associativity conflicts [6]. With Morton layout, it turns out to be important to consider padding the base address of the array. In our discussion of the cache hit rate resulting from Morton order arrays in the previous Section, we have implicitly assumed that the base address of the array will be mapped to the start of a cache line. For a 32 byte, i.e. 2 2 double word cache line, this would mean that the base address of the Morton array is 32-byte aligned. As we have illustrated previously in Section 2, such an allocation is unbiased towards any particular order of traversal. However, in Figure 3 we show that if the allocated array is offset from this “perfect” alignment, Morton layout may no longer be an unbiased compromise storage layout.
The average miss-rate of traversing the array, both in row- and in column-major order, is always worse when the alignment of the base address is offset from the alignment of a 4-word cache line. When the array is mis-aligned, we lose the symmetry property of Morton order being an unbiased compromise between row- and column-major storage layout.
Systematic study across different levels of memory hierarchy. In order to investigate this effect further, we systematically calculated the resulting missrates for both row- and column-major traversal of Morton arrays, over a range of possible levels of memory hierarchy, and for each level, different miss-alignments of the base address of Morton arrays. The range of block sizes in memory hierarchy we covered was from 22 double words, corresponding to a 32-byte cache line to 210 double words, corresponding to an 8kB page. Architectural considerations imply that block sizes in the memory hierarchy such as cache lines or pages have a power-of-two size. For each 2n block size, we calculated, over all possible alignments of the base address of a Morton array with respect to this block size, respectively the best, worst and average resulting miss-rates for both row-major and column-major traversal of the array. The standard C library malloc() function returns addresses which are double-word aligned. We therefore conducted our study at the resolution of double words. The results of our calculation are summarised in Figure 4. Based on those results, we offer the following conclusions. 1. The average miss-rate is the performance that might be expected when no special steps are taken to align the base address of a Morton array 1 . We note that the miss rates resulting from such alignments is always suboptimal. 2. The best average hit rates for both row- and column-major traversal are always achieved by aligning the base address of Morton array to the largest significant block size of memory hierarchy (e.g. page size). 3. The difference between the best and the worst miss-rates can be very significant, up to a factor of 2 for both row-major and column-major traversal. 4. We observe that the symmetry property which we mentioned in Section 2 as a motivation for using Morton storage layout is in fact only available when using the best alignment and for even power-of-two block sizes 1 In reality, some operating systems do not return randomly aligned addressed (modulo double word size). Linux, for example, seems to consistently return “page plus 8 bytes” addresses for large arrays. However, these are consistently sub-optimal for Morton arrays.
6
Section 3: Alignment of the Base Address of Morton Arrays
0
2 8 10
1111 0000 0000 1111 1 1111 4 5 4 5 0000 0000 1111 0000 1111 0000 1111 2 3 1111 6 7 3 1111 6 7 0000 0000 11 00 1111 0000 0000 1111 8 9 12 13 12 13 9 00 11 00 11 10 11 14 15 11 14 15
1
2
0
2
3
2
2
4 2 4 2 Average Hit Rate RM CM 37.5% 25%
4 5 4 5 1 1111 0000 00 11 2 3 1111 6 7 6 11 2 3 7 0000 00 0000 1111 1111 0000 0000 1111 00 11 12 13 8 9 8 9 12 13 0000 1111 0000 1111 0000 1111 0000 1111 10 11 14 15 10 11 14 15 0000 1111 0000 1111 1
4 4 4 4 Average Hit Rate RM CM 50% 0%
2
0
Misses per row
2
2
2 2 2 2 Average Hit Rate RM CM 50% 50% 0
3
Misses per column
2
2
3
2
2
2
3
2 4 2 4 Average Hit Rate RM CM 37.5% 25%
Figure 3: Alignment of Morton-order Arrays. This figure shows the impact of mis-aligning the base address of a 4 4
Morton array from the alignment of a 4-word cache line. The numbers next to each row and below each column indicate the number of misses encountered when traversing a row (column) of the array in row-major (column-major) order, considering only spatial locality. Underneath each diagram, we show the average theoretical hit rate for the entire Morton array for both row-major (RM) and column-major (CM) traversal.
in the memory hierarchy. For odd power-of-two block sizes (such as 23 = 8 double words, corresponding to a 64-byte cache line), we find that the Z-Morton layout, which we use, is still significantly biased towards row-major traversal. An alternative recursive layout [4] may have better properties in this respect. 5. The absolute miss-rates we observe drop exponentially through increasing levels of the memory hierarchy (see the graphs in Figure 4). However, if we assume that not only the block size but also the access time of different levels of memory hierarchy increase exponentially [1], the penalty of miss-alignment of Morton arrays does not degrade significantly for larger block sizes. From a theoretical point of view, we therefore recommend aligning the base address of all Morton arrays to the largest significant block size in the memory hierarchy, i.e. page size. In real machines, there are conflicting performance issues apart from maximising spatial locality, such as aliasing of addresses that are identical modulo some power-of-two, and some of these could negate the benefits of increased spatial locality resulting from making the base address of Morton arrays page-aligned.
3.1 Experimental Evaluation of Impact of Alignment of Morton Arrays In our experimental evaluation, we have studied the impact on actual performance of the alignment of the base address of Morton arrays. For each architecture and each benchmark, we have measured the performance of Morton layout both when using the system’s default alignment (i.e. addresses as returned by malloc()) and when aligning arrays to each significant size of memory hierarchy.
3.1 Experimental Evaluation of Impact of Alignment of Morton Arrays
Memory Hierarchy Miss Rates for Row-Major Traversal of a Morton Array
1
CM Maximum CM Minimum CM Average
0.9 0.8
0.7
0.7
0.6
0.6
Miss Rate
Miss Rate
0.8
Memory Hierarchy Miss Rates for Column-Major Traversal of a Morton Array
1
RM Maximum RM Minimum RM Average
0.9
7
0.5 0.4
0.5 0.4
0.3
0.3
0.2
0.2
0.1
0.1 0
0 4
8
16
32
64
128
256
512
4
1024
8
16
Blocksize in Double Words
32
64
128
256
512
1024
Blocksize in Double Words
..... Memory Hierarchy Miss Rates for Row-Major and Column-Major Traversal of a Morton Array
1
Miss Rate
RM Average CM Average
0.1
0.01 1
2
3
4
5
6
7
8
9
10
11
log2(Blocksize in Double Words)
Figure 4: Miss-rates for row-major and column-major traversal of Morton arrays. We show the best, worst and average miss-rates for different units of memory hierarchy (referred to as blocksizes), across all possible alignments of the base address of the Morton array. The top two graphs, use a linear y-axis, whilst the graph underneath uses a logarithmic y-axis to illustrate that the pattern of missrates is in fact highly structured across all levels of the memory hierarchy.
Benchmark kernels and architectures. To test our hypothesis that Morton layout, implemented using lookup tables, is a useful compromise between row-major and column-major layout experimentally, we have collected a suite of simple implementations of standard numerical kernels operating on two-dimensional arrays and carried out experiments on five different architectures. The benchmarking kernels used are shown in Table 2 and the platforms in Table 3. Performance Results. Figures 5–8 show our results, when varying the base address of the Morton order arrays, in detail and we make some comments directly in the figures. We have carried out extensive measurements over a full range of problem sizes: the data underlying the graphs in Figures 5–8 consist of more than 25 million individual measurements. For each experiment / architecture pair, we give a broad characterisation of whether Morton layout is a useful compromise between row-major and column-major in this setting by annotating the figures with win, lose, etc. Summary. For all experiments, except for MMijk on Athlon, our theoretical conclusions from Section 3 are supported by our experimental data: Padding the base address of Morton order arrays to a significant size in the memory hierarchy, such as cache line size or page size can significantly improve performance. Our theoretical assertion that aligning with the largest significant block size in the memory hierarchy, i.e. page size, should always be best is supported in most, but not all cases by our experimental data, and we assume that where this is not the case (such as MMijk on Alpha), this is due to interference effects. In some cases, specifically Adi on P3, Jacobi on Sparc and MMikj on P4, the improvement with page-alignment is quite significant and can in fact be the key
8
Section 3: Alignment of the Base Address of Morton Arrays
Adi Alternating-direction implicit kernel, ij-ij order min max 27.0 84.5 43.8 210.4 13.7 46.6 46.2 134.1 11.4 54.3
Alpha Athlon P3 P4 Sparc
Jacobi2D Two-dimensional fourpoint stencil smoother min max 24.2 167.1 150.6 1078.6 38.7 122.3 159.6 1337.3 33.2 138.6
MMijk Matrix multiply, ijk loop nest order min max 6.0 139.5 9.5 262.5 15.5 91.8 12.6 147.3 5.0 131.9
MMikj Matrix multiply, ikj loop nest order min max 37.6 177.0 118.2 884.2 43.9 153.8 281.4 939.1 20.5 142.8
Table 2: Numerical kernels used in our evaluation, together with their baseline performance on the different platforms used. For each kernel, for each machine, we show the performance range in MFLOPs for row-major array layout over all problem sizes covered in our experiments (as shown in Figures 5– 8). System
Processor
Operating System OSF1 V5.0
Alpha Compaq AlphaServer ES40 Sun SunFire 6800
Alpha 21264 (EV6) 500MHz
UltraSparcIII(v9) 750MHz
SunOS 5.8
PIII
PentiumIII Coppermine 450MHz
Linux 2.4.20
P4
Pentium 4 2.0 GHz
Linux 2.4.20
AMD
AMD Athlon XP 2100+ 1.8GHz
Linux 2.4.20
L1/L2/Memory Parameters L1 D-cache: 2-way, 64KB, 64B cache line L2 cache: direct mapped, 4MB Page size: 8KB Main Memory: 4GB RAM L1 D-cache: 4-way, 64KB, 32B cache line L2 cache: direct-mapped, 8MB Page size: 8KB Main Memory: 24GB L1 D-cache: 4-way, 16KB, 32B cache line L2 cache: 4-way 512KB, sectored 32B cache line Page size: 4KB Main Memory: 256MB SDRAM L1 D-cache: 4-way, 8KB, sectored 64B cache line L2 cache: 8-way, 512KB, sectored 128B cache line Page size: 4KB Main Memory: 512MB DDR-RAM L1 D-Cache: 2-way, 64KB, 64B cache line L2 cache: 16-way, 256KB, 64B cache line Page size: 4KB Main Memory: 512MB DDR-RAM
Compiler and Flags Used Compaq C Compiler V6.1-020 -arch ev6 -fast -O4 Sun Workshop 6 -fast -xcrossfile -xalias level=std Intel C/C++ Compiler v7.00 -xK -mp -ipo -O3 -static Intel C/C++ Compiler v7.00 -xW -mp -ipo -O3 -static Intel C/C++ Compiler v7.00 -xK -mp -ipo -static
Table 3: Cache and CPU configurations used in the experiments. Compilers and compiler flags match those used by the vendors in their SPEC CFP2000 (base) benchmark reports [7].
to making Morton storage layout perform well compared to the worse of the two canonical layouts.
3.1 Experimental Evaluation of Impact of Alignment of Morton Arrays
Win over CM for problem sizes larger than about 362 362
Win over CM for problem sizes larger than about 700 700
Adi on Alpha: Performance in MFLOP/s (Alignment) 120
80 60 40 20 0 100
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 64-Byte Aligned Morton 8192-Byte Aligned
50 Performance in MFLOP/s
Performance in MFLOP/s
Adi on Sparc: Performance in MFLOP/s (Alignment) 60
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 8192-Byte Aligned
100
9
40 30 20 10 0
200
300
400
500
600
700
800
900
1000
500
Square Root of Datasize
Lose
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 4096-Byte Aligned
45 Performance in MFLOP/s
Performance in MFLOP/s
2000
Adi on P3: Performance in MFLOP/s (Alignment) 50
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 4096-Byte Aligned
200
1500
Win over CM with Alignment
Adi on Athlon: Performance in MFLOP/s (Alignment) 250
1000
Square Root of Datasize
150
100
50
40 35 30 25 20 15 10 5
0
0 500
1000 1500 Square Root of Datasize
2000
Lose
Adi on P4: Performance in MFLOP/s (Alignment) 140
Performance in MFLOP/s
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 128-Byte Aligned Morton 4096-Byte Aligned
120 100
500
80 60
40 20
1000 1500 Square Root of Datasize
2000
Notice for Alpha, the upper limit is 1024 1024. For Alpha (Sun), the fall-off in RM performance occurs at 725 725 (1024 1024) when the total datasize exceeds L2 cache size o f 4MB (8MB) , direct mapped. This assumes a working set of 725 725 (1024 1024) doubles. Alignment significantly improves performance of the default Morton layout on P3. On other platforms, alignment also yields slight improvements.
0 500
1000 1500 Square Root of Datasize
2000
Figure 5: ADI performance in MFLOPs on different platforms. We compare row-major (RM), column-major (CM) and Morton implemented using lookup tables. The base address of the Morton order array was varied and aligned at siginificant sizes in the memory hierarchy.
10
Section 3: Alignment of the Base Address of Morton Arrays
Win over CM for problem sizes larger than about 330 330
Win over CM for problem sizes larger than about 600 600
Jacobi2D on Alpha: Performance in MFLOP/s (Alignment) 180
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 8192-Byte Aligned
140
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 64-Byte Aligned Morton 8192-Byte Aligned
120 Performance in MFLOP/s
Performance in MFLOP/s
160
Jacobi2D on Sparc: Performance in MFLOP/s (Alignment) 140
120 100 80 60 40
100 80 60 40 20
20 0
0 500
1000
1500
2000
500
Square Root of Datasize
Lose
Performance in MFLOP/s
Performance in MFLOP/s
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 4096-Byte Aligned
120
800 600 400 200
100 80 60 40 20
0
0 500
1000 1500 Square Root of Datasize
2000
Lose Jacobi2D on P4: Performance in MFLOP/s (Alignment) 1400
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 128-Byte Aligned Morton 4096-Byte Aligned
1200 Performance in MFLOP/s
2000
Jacobi2D on P3: Performance in MFLOP/s (Alignment) 140
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 4096-Byte Aligned
1000
1500
Lose
Jacobi2D on Athlon: Performance in MFLOP/s (Alignment) 1200
1000
Square Root of Datasize
1000
500
800 600
1000 1500 Square Root of Datasize
2000
L2-aligned version on Alpha, and page-aligned on other platforms, improves basic Morton performance. Unrolling improves performance of the best aligned Morton implementation, in particular on x86 where the unrolled Morton performance is within reach of the best canonical.
400 200 0 500
1000 1500 Square Root of Datasize
2000
Figure 6: Jacobi2D performance in MFLOPs on different platforms. We compare row-major (RM), columnmajor (CM) and Morton implemented using lookup tables. The base address of the Morton order array was varied and aligned at siginificant sizes in the memory hierarchy.
3.1 Experimental Evaluation of Impact of Alignment of Morton Arrays
Win over CM for problem sizes larger than about 330 330
Win over CM for problem sizes larger than about 500 500
MMikj on Alpha: Performance in MFLOP/s (Alignment)
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 64-Byte Aligned Morton 8192-Byte Aligned
140 Performance in MFLOP/s
Performance in MFLOP/s
MMikj on Sparc: Performance in MFLOP/s (Alignment) 160
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 8192-Byte Aligned
200
11
150
100
50
120 100 80 60 40 20
0 100
0 200
300
400
500
600
700
800
900
1000
500
Square Root of Datasize
Lose
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 4096-Byte Aligned
140 Performance in MFLOP/s
Performance in MFLOP/s
700
2000
MMikj on P3: Performance in MFLOP/s (Alignment) 160
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 4096-Byte Aligned
800
1500
Lose
MMikj on Athlon: Performance in MFLOP/s (Alignment) 900
1000
Square Root of Datasize
600 500 400 300 200
120 100 80 60 40 20
100 0 500
1000 1500 Square Root of Datasize
2000
0 100
200
300
400 500 600 700 800 Square Root of Datasize
900
1000
Marginal Win MMikj on P4: Performance in MFLOP/s (Alignment) 1000
Performance in MFLOP/s
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 128-Byte Aligned Morton 4096-Byte Aligned
900 800 700
600
For Alpha, notice that upper limit is 1024 1024. Alignment causes a small improvement in Morton performance on all platforms except Athlon.
500 400 300 200 100 0 500
1000
1500
2000
Square Root of Datasize
Figure 7: MMikj performance in MFLOPs on different platforms. We compare row-major (RM), columnmajor (CM) and Morton implemented using lookup tables. The base address of the Morton order array was varied and aligned at siginificant sizes in the memory hierarchy.
12
Section 3: Alignment of the Base Address of Morton Arrays
Win over both RM and CM for problem sizes larger than about 360 360
Win over both RM and CM for problem sizes larger than about 750 750
MMijk on Alpha: Performance in MFLOP/s (Alignment) 140
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 8192-Byte Aligned
100 80 60 40 20 0 100
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 64-Byte Aligned Morton 8192-Byte Aligned
140 Performance in MFLOP/s
120 Performance in MFLOP/s
MMijk on Sparc: Performance in MFLOP/s (Alignment) 160
120 100 80 60 40 20
200
300
400 500 600 700 800 Square Root of Datasize
900
0 100
1000
200
300
400 500 600 700 800 Square Root of Datasize
Lose
MMijk on P3: Performance in MFLOP/s (Alignment) RM Default Alignment CM Default Alignment Morton Default Alignment Morton 32-Byte Aligned Morton 4096-Byte Aligned
90 Performance in MFLOP/s
Performance in MFLOP/s
100
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 4096-Byte Aligned
250
1000
Lose
MMijk on Athlon: Performance in MFLOP/s (Alignment) 300
900
200 150 100 50
80 70 60 50 40 30 20 10
0 500
1000
1500
2000
0 100
Lose
MMijk on P4: Performance in MFLOP/s (Alignment)
Performance in MFLOP/s
200
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 64-Byte Aligned Morton 128-Byte Aligned Morton 4096-Byte Aligned
150
200
300
400
500
600
700
800
900
1000
Square Root of Datasize
Square Root of Datasize
100
For Alpha, notice that the upper limit is 1024 1024. Notice the sharp drop in RM and CM performance on Alpha (around 360 360) and on Sparc (around 700 700) platforms . Page-aligned Morton is marginally faster than default on most platforms. However, on Alpha L2-aligned is faster than page-aligned.
50
0 500
1000
1500
2000
Square Root of Datasize
Figure 8: MMijk performance in MFLOPs on different platforms. We compare row-major (RM), columnmajor (CM) and Morton implemented using lookup tables. The base address of the Morton order array was varied and aligned at siginificant sizes in the memory hierarchy.
Section 4: Unrolling Loops over Morton Arrays
13
4 Unrolling Loops over Morton Arrays
Linear array layouts have the following property. Let L ( ij ) be the address calculation function which returns the offset from the array base address at which the element identified by index vector ij is stored. Then, for any offset-vector kl , we have L ij + kl = L ij + L kl . (1) As an example, for a row-major array A, A(i; j + k) is stored at location A(i; j) + k. Compilers can exploit this transformation when unrolling loops over arrays with linear array layouts by strength-reducing the address calculation for all except the first loop iteration in the unrolled loop body to simple addition of a constant. As stated in Section 2, the Morton address mapping is Smz (i; j) = D1 (i) j D0 ( j), where “j” denotes bitwise-or, which can be implemented as addition. Given offset k,
Smz (i; j + k) = D1 (i) j D0 ( j + k) = D1 (i) + D0 ( j + k) . The problem is that there is no general way of simplifying D0 ( j + k) for all j and all k. Proposition 4.1 (Strength-reduction of Morton address calculation). Let u be some power-of-two number such that u = 2n . Assume that j mod u = 0 and that k < u. Then,
D0 ( j + k) = D0 ( j) + D0 (k)
.
(2)
This follows from the following observations: If j mod u = 0 then the n least significant bits of j are zero; if k < u then all except the n least significant bits of k are zero. Therefore, the dilated addition D0 ( j + k) can be performed separately on the n least significant bits of j. As an example, assume that j mod 4 = 0. Then, the following strength-reductions of Morton order address calculation are valid:
Smz (i; j + 1) Smz (i; j + 2) Smz (i; j + 3)
= = =
D1 (i) + D0 ( j) + 1 D1 (i) + D0 ( j) + 4 D1 (i) + D0 ( j) + 5 .
An analogous result holds for the i index. Therefore, by carefully choosing the alignment of the starting loop iteration variable with respect to the array indices used in the loop body and by choosing a power-of-two unrolling factor, loops over Morton order arrays can benefit from strength-reduction in unrolled loops. In our implementation, using table lookups, this means that memory references for the Morton tables are replaced by simple addition of constants. Existing production compilers cannot find this transformation automatically. We therefore implemented this unrolling scheme by hand in order to quantify the possible benefit. We report very promising initial performance results in Section 3.1.
4.1 Experimental Evaluation of Unrolling of Morton Arrays Impact of Unrolling. By inspecting the assembly codes generated by the compilers, we established that at least the icc compiler on x86 architectures does automatically unroll the loops wherever possible for row-major layout. Helping the compiler to unroll the loops over Morton arrays as described in Section 4 can result in a significant performance improvement of the Morton code: On all three x86 architectures, the unrolled Morton code is very close to the performance of the best canonical code, i.e. row-major. We plan to explore this promising result further by investigating different unrolling factors. Our experimental methodology for unrolling is same as described in Section 3.1 but with the unrolled implementations. Performance results are illustrated in Figures 9–12.
14
Section 4: Unrolling Loops over Morton Arrays
Win over CM
Win over CM
Adi on Alpha: Performance in MFLOP/s (Unrolling) 120
80 60 40 20 0 100
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
60 Performance in MFLOP/s
100 Performance in MFLOP/s
Adi on Sparc: Performance in MFLOP/s (Unrolling) 70
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
50 40 30 20 10 0
200
300
400
500
600
700
800
900
1000
500
Square Root of Datasize
Marginal Win
200 150 100 50
40 35 30 25 20 15 10 5
0
0 500
1000 1500 Square Root of Datasize
2000
Adi on P4: Performance in MFLOP/s (Unrolling) 250
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled
200
500
1000
1500
2000
Square Root of Datasize
Mariginal Win
Performance in MFLOP/s
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled Morton 4096-Byte Aligned Unrolled-Packed
45 Performance in MFLOP/s
Performance in MFLOP/s
250
2000
Adi on P3: Performance in MFLOP/s (Unrolling) 50
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled
300
1500
Win over CM with Alignment
Adi on Athlon: Performance in MFLOP/s (Unrolling) 350
1000
Square Root of Datasize
150
100
50
Notice for Alpha, the upper limit is 1024 1024. For Alpha (Sun), the fall-off in RM performance occurs at 725 725 (1024 1024) when the total datasize exceeds L2 cache size o f 4MB (8MB) , direct mapped. This assumes a working set of 725 725 (1024 1024) doubles. Alignment significantly improves performance of the default Morton array on P3. On other platforms, alignment also yields slight improvements.
0 500
1000 1500 Square Root of Datasize
2000
Figure 9: ADI performance in MFLOPs on different platforms. We compare row-major, column-major, Morton with default alignment of the base address of the array, Morton with page-aligned base address and unrolledMorton with page-aligned base address and factor 4 loop unrolling.
4.1 Experimental Evaluation of Unrolling of Morton Arrays
15
Win over CM
Win over CM for problem sizes larger than about 600 600
Jacobi2D on Alpha: Performance in MFLOP/s (Unrolling) 180
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
140
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
120 Performance in MFLOP/s
Performance in MFLOP/s
160
Jacobi2D on Sparc: Performance in MFLOP/s (Unrolling) 140
120 100 80 60 40
100 80 60 40 20
20 0
0 500
1000
1500
2000
500
Square Root of Datasize
Win over CM
Performance in MFLOP/s
Performance in MFLOP/s
600 400 200
1000 1500 Square Root of Datasize
60 40
2000
Marginal Win/Win over CM
500
Jacobi2D on P4: Performance in MFLOP/s (Unrolling)
Performance in MFLOP/s
80
0 500
1000
100
20
0
1200
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled Morton 4096-Byte Aligned Unrolled-Packed
120
800
1400
2000
Jacobi2D on P3: Performance in MFLOP/s (Unrolling) 140
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled
1000
1500
Win over CM
Jacobi2D on Athlon: Performance in MFLOP/s (Unrolling) 1200
1000
Square Root of Datasize
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled Morton 4096-Byte Aligned Unrolled-Packed
800 600
1000 1500 Square Root of Datasize
2000
L2-aligned version on Alpha, and page-aligned on other platforms, improves basic Morton performance. Unrolling improves performance of the best aligned Morton implementation, in particular on x86 where the unrolled Morton performance is within reach of the best canonical.
400 200 0 500
1000 1500 Square Root of Datasize
2000
Figure 10: Jacobi2D performance in MFLOPs on different platforms. We compare row-major, column-major, Morton with default alignment of the base address of the array, Morton with page-aligned base address and Morton with page-aligned base address and factor 4 loop unrolling.
16
Section 4: Unrolling Loops over Morton Arrays
Win over CM for problem sizes larger than about 330 330
Win over CM for problem sizes larger than about 500 500
MMikj on Alpha: Performance in MFLOP/s (Unrolling) RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
140 Performance in MFLOP/s
200 Performance in MFLOP/s
MMikj on Sparc: Performance in MFLOP/s (Unrolling) 160
150
100
50
120 100 80 60 40 20
0 100
0 200
300
400
500
600
700
800
900
1000
500
Square Root of Datasize
Marginal Win/Win over CM
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled Morton 4096-Byte Aligned Unrolled-Packed
140 Performance in MFLOP/s
Performance in MFLOP/s
700
2000
MMikj on P3: Performance in MFLOP/s (Unrolling) 160
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled
800
1500
Marginal Win/Win over CM
MMikj on Athlon: Performance in MFLOP/s (Unrolling) 900
1000
Square Root of Datasize
600 500 400 300 200
120 100 80 60 40 20
100 0 500
1000 1500 Square Root of Datasize
2000
0 100
200
300
400 500 600 700 800 Square Root of Datasize
900
1000
Win over CM MMikj on P4: Performance in MFLOP/s (Unrolling) 1000
Performance in MFLOP/s
900 800 700
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled Morton 4096-Byte Aligned Unrolled-Packed
600
For Alpha, notice that upper limit is 1024 1024. Alignment causes a small improvement in Morton performance on all platforms except Athlon.
500 400 300 200 100 0 500
1000
1500
2000
Square Root of Datasize
Figure 11: MMikj performance in MFLOPs on different platforms. We compare row-major, column-major, Morton with default alignment of the base address of the array, Morton with page-aligned base address and Morton with page-aligned base address and factor 4 loop unrolling.
4.1 Experimental Evaluation of Unrolling of Morton Arrays
17
Win over both RM and CM for problem sizes larger than about 360 360
Win over both RM and CM for problem sizes larger than about 750 750
MMijk on Alpha: Performance in MFLOP/s (Unrolling) 140
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
100
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 8192-Byte Aligned Morton 8192-Byte Aligned Unrolled
140 Performance in MFLOP/s
120 Performance in MFLOP/s
MMijk on Sparc: Performance in MFLOP/s (Unrolling) 160
80 60 40 20
120 100 80 60 40 20
0 100
200
300
400
500
600
700
800
900
0 100
1000
200
300
Square Root of Datasize
Win over both RM and CM for problem sizes smaller than about 1200 1200
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled
90 Performance in MFLOP/s
Performance in MFLOP/s
400 350 300 250 200 150 100
80 70 60 50 40 30 20 10
50 0 500
1000
1500
2000
0 100
Square Root of Datasize
Win over both RM and CM for problem sizes smaller than about 1200 1200
MMijk on P4: Performance in MFLOP/s (Unrolling) 500
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled
450 Performance in MFLOP/s
1000
MMijk on P3: Performance in MFLOP/s (Unrolling) 100
RM Default Alignment CM Default Alignment Morton Default Alignment Morton 4096-Byte Aligned Morton 4096-Byte Aligned Unrolled
450
900
Marginal Win/Win over CM
MMijk on Athlon: Performance in MFLOP/s (Unrolling) 500
400 500 600 700 800 Square Root of Datasize
400 350
300 250 200
200
300
400 500 600 700 800 Square Root of Datasize
900
1000
For Alpha, notice that the upper limit is 1024 1024. Notice the sharp drop in RM and CM performance on Alpha (around 360 360) and on Sparc (around 700 700) platforms . Page-aligned Morton is marginally faster than default on most platforms. However, on Alpha L2-aligned is faster than page-aligned.
150 100 50 0 500
1000
1500
2000
Square Root of Datasize
Figure 12: MMijk performance in MFLOPs on different platforms. We compare row-major, column-major, Morton with default alignment of the base address of the array, Morton with page-aligned base address and Morton with page-aligned base address and factor 4 loop unrolling.
18
REFERENCES
5 Related Work Chatterjee et al. [3] study Morton layout and a blocked “4D” layout. They focus on tiled implementations, for which they find that the 4D layout achieves higher performance than the Morton layout because the address calculation problem is easier, while much or all the spatial locality is still exploited. Their work has similar goals to ours, but all their benchmark applications are tiled (or “shackled”) for temporal locality; they show impressive performance, with the further advantage that performance is less sensitive to small changes in tile size and problem size, which can result in cache associativity conflicts with conventional layouts. In contrast, the goal of our work is to evaluate whether Morton layout can simplify the performance programming model for unsophisticated programmers, without relying on very powerful compiler technology. In [11] Wise et al. argue for compiler-support for Morton order matrices. They use the recursive implementation of the Morton layout, with the base case being manually unfolded and re-rolled, to compare against the BLAS-3 [2]. They justify that such a technique is valid as optimising compilers should provide similar support for small loops. However, they find it hard to overcome the cost of addressing without recursion. Rivera et al. [6] examine intra- and inter- variable padding schemes to ameliorate the effects of conflict misses, as compile-time techniques. The inter-variable padding scheme, which uses heuristics to guide the process of padding, adjusts the base address of the variable upon detecting conflicts with another array or variable(s).
6 Conclusions We believe that work on nonlinear storage layouts, such as Morton order, is applicable in a number of different areas.
Simplifying the performance-programming model. A simple performance-programming model is one important objective of language design and compilerwriting. Achieving this without sacrificing too much performance is probably just as important. We believe that the work presented in this techincal report can be a contribution towards reducing the price of the attractive properties offered by Morton layout over canonical layouts. Storage layout transformations complement code restructuring. Storage layout transformations are always valid and can thus be applied even in codes where restructuring such as tiling is not valid, or where the validity of such transformations is too hard to prove. However, even in tiled codes, using storage layout transformations can be an additional and complementary optimisation.
References [1] Bowen Alpern, Larry Carter, Ephraim Feig, and Ted Selker. The uniform memory hierarchy model of computation. Algorithmica, 12(2/3):72–109, August/September 1994. [2] BLAST Forum. Basic linear algebra subprograms technical BLAST forum standard, August 2001. Available via www.netlib.org/blas/blas-forum. [3] Siddhartha Chatterjee, Vibhor V. Jain, Alvin R. Lebeck, Shyam Mundhra, and Mithuna Thottethodi. Nonlinear array layouts for hierarchical memory systems. In ICS ’99: Proceedings of the 1999 International Conference on Supercomputing, pages 444–453, June 20–25, 1999. [4] Siddhartha Chatterjee, Alvin R. Lebeck, Praveen K. Patnala, and Mithuna Thottethodi. Recursive array layouts and fast parallel matrix multiplication. In SPAA ’99: Eleventh Annual ACM Symposium on Parallel Algorithms and Architectures, pages 222–231, New York, June 1999. [5] Peter Drakenberg, Fredrik Lundevall, and Bj¨orn Lisper. An efficient semi-hierarchical array layout. In Proceedings of the Workshop on Interaction between Compilers and Computer Architectures, Monterrey, Mexico, January 2001. Kluwer. Available via www.mrtc.mdh.se. [6] Gabriel Rivera and Chau-Wen Tseng. Data transformations for eliminating conflict misses. In PLDI ’98: Proceedings of the ACM SIGPLAN’98 Conference on Programming Language Design and Implementation, pages 38–49, Montreal, Canada, 17–19 June 1998.
REFERENCES
19
[7] www.specbench,org. [8] Jeyarajan Thiyagalingam, Olav Beckmann, and Paul H. J. Kelly. An exhaustive evaluation of row-major, column-major and Morton layouts for large two-dimensional arrays. In Stephen A. Jarvis, editor, Performance Engineering: 19th Annual UK Performance Engineering Workshop, pages 340–351. University of Warwick, UK, July 2003. [9] Jeyarajan Thiyagalingam and Paul H J Kelly. Is morton layout competitive for large two-dimensional arrays? In Euro-Par 2002 Parallel Processing: Proceedings of the 8th International Euro-Par Conference, number 2400 in LNCS, pages 280–288, August 2002. [10] Vinod Valsalam and Anthony Skjellum. A framework for high-performance matrix multiplication based on hierarchical abstractions, algorithms and optimized low-level kernels. Concurrency and Computation: Practice and Experience, 14(10):805–839, August 2002. [11] David S. Wise and Jeremy D. Frens. Morton-order Matrices Deserve Compilers’ Support. Technical Report, TR533, November 1999. [12] David S. Wise, Jeremy D. Frens, Yuhong Gu, and Gregory A. Alexander. Language support for Morton-order matrices. ACM SIGPLAN Notices, 36(7):24–33, July 2001. Proceedings of PPoPP 2001.