







Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Cache-oblivious algorithms for matrix transpose, fft, and sorting on computers with multiple levels of caching. The algorithms aim to minimize both work complexity and cache complexity. Detailed analysis of cache complexity for matrix multiplication using the rec-mult algorithm and discusses the cache complexity of other algorithms such as strassen's algorithm and rec-transpose.
Typology: Papers
1 / 13
This page cannot be seen from the preview
Don't miss anything!








MIT Laboratory for Computer Science !, 545 Technology Square "##$ %'&( #, Cambridge, MA 02139 &*)+%,&-"
Abstract This paper presents asymptotically optimal algo- rithms for rectangular matrix transpose, FFT, and sorting on computers with multiple levels of caching. Unlike previous optimal algorithms, these algorithms are cache oblivious : no variables dependent on hardware parameters, such as cache size and cache-line length, need to be tuned to achieve opti- mality. Nevertheless, these algorithms use an optimal amount of work and move data optimally among multiple levels of cache. For a cache with size Z and cache-line length L where Z. Ω / L^2 0 the number of cache misses for an m 1 n ma- trix transpose is Θ / 1 2 mn 3 L^0. The number of cache misses for either an n -point FFT or the sorting of n numbers is Θ/ 1 2 4/ n 3 L^0 / 1 2 log Z n^0 50. We also give an Θ / mnp^0 -work al- gorithm to multiply an m 1 n matrix by an n 1 p matrix that incurs Θ / 1 2 6/ mn 2 np 2 mp 03 L 2 mnp 3 L 7 Z 0 cache faults. We introduce an “ideal-cache” model to analyze our algo- rithms. We prove that an optimal cache-oblivious algorithm designed for two levels of memory is also optimal for multi- ple levels and that the assumption of optimal replacement in the ideal-cache model can be simulated efficiently by LRU re- placement. We also provide preliminary empirical results on the effectiveness of cache-oblivious algorithms in practice.
Resource-oblivious algorithms that nevertheless use re- sources efficiently offer advantages of simplicity and portability over resource-aware algorithms whose re- source usage must be programmed explicitly. In this paper, we study cache resources, specifically, the hier- archy of memories in modern computers. We exhibit several “cache-oblivious” algorithms that use cache as effectively as “cache-aware” algorithms. Before discussing the notion of cache obliviousness, we first introduce the 8 Z 9 L : ideal-cache model to study the cache complexity of algorithms. This model, which is illustrated in Figure 1, consists of a computer with a two-level memory hierarchy consisting of an ideal (data) cache of Z words and an arbitrarily large main mem- ory. Because the actual size of words in a computer is typically a small, fixed size (4 bytes, 8 bytes, etc.), we
This research was supported in part by the Defense Advanced Research Projects Agency (DARPA) under Grant F30602-97-1-0270. Matteo Frigo was supported in part by a Digital Equipment Corpora- tion fellowship.
cache misses
organized by optimal replacement strategy
Main Memory
Cache
Z 3 L Cache lines
Lines of length L
CPU W work
Figure 1: The ideal-cache model
shall assume that word size is constant; the particular constant does not affect our asymptotic analyses. The cache is partitioned into cache lines , each consisting of L consecutive words which are always moved together between cache and main memory. Cache designers typ- ically use L ; 1, banking on spatial locality to amortize the overhead of moving the cache line. We shall gener- ally assume in this paper that the cache is tall : Z < Ω 8 L^2 :9 (1)
which is usually true in practice. The processor can only reference words that reside in the cache. If the referenced word belongs to a line already in cache, a cache hit occurs, and the word is delivered to the processor. Otherwise, a cache miss oc- curs, and the line is fetched into the cache. The ideal cache is fully associative [20, Ch. 5]: cache lines can be stored anywhere in the cache. If the cache is full, a cache line must be evicted. The ideal cache uses the optimal off-line strategy of replacing the cache line whose next access is furthest in the future [7], and thus it exploits temporal locality perfectly. Unlike various other hierarchical-memory models [1, 2, 5, 8] in which algorithms are analyzed in terms of a single measure, the ideal-cache model uses two mea- sures. An algorithm with an input of size n is measured by its work complexity W 8 n :—its conventional running time in a RAM model [4]—and its cache complexity Q 8 n ; Z 9 L : —the number of cache misses it incurs as a
function of the size Z and line length L of the ideal cache. When Z and L are clear from context, we denote the cache complexity simply as Q 8 n : to ease notation. We define an algorithm to be cache aware if it con- tains parameters (set at either compile-time or runtime) that can be tuned to optimize the cache complexity for the particular cache size and line length. Otherwise, the algorithm is cache oblivious. Historically, good perfor- mance has been obtained using cache-aware algorithms, but we shall exhibit several optimal^1 cache-oblivious al- gorithms. To illustrate the notion of cache awareness, consider the problem of multiplying two n n matrices A and B to produce their n n product C. We assume that the three matrices are stored in row-major order, as shown in Figure 2(a). We further assume that n is “big,” i.e., n ; L , in order to simplify the analysis. The conventional way to multiply matrices on a computer with caches is to use a blocked algorithm [19, p. 45]. The idea is to view each matrix M as consisting of 8 n
s : 8 n
s : submatrices Mi j (the blocks), each of which has size s s , where s is a tuning parame- ter. The following algorithm implements this strategy:
BLOCK-MULT / A B C n^0 1 for i 1 to n 3 s 2 do for j 1 to n 3 s 3 do for k 1 to n 3 s 4 do ORD-MULT / Aik Bk j Ci j s^0
The ORD-MULT 8 A 9 B 9 C 9 s : subroutine computes C C AB on s s matrices using the ordinary O 8 s^3 : algorithm. (This algorithm assumes for simplicity that s evenly divides n , but in practice s and n need have no special relationship, yielding more complicated code in the same spirit.) Depending on the cache size of the machine on which BLOCK-MULT is run, the parameter s can be tuned to make the algorithm run fast, and thus BLOCK-MULT is a cache-aware algorithm. To minimize the cache com- plexity, we choose s to be the largest value such that the three s s submatrices simultaneously fit in cache. An s s submatrix is stored on Θ 8 s s^2 L : cache lines. From the tall-cache assumption (1), we can see that s < Θ 8 Z :. Thus, each of the calls to ORD-MULT runs with at most Z
L < Θ 8 s^2 L : cache misses needed to bring the three matrices into the cache. Consequently, the cache complexity of the entire algorithm is Θ 8 1
n^2 L 8 n
Z :^3 8 Z
L : :< Θ 81 n^2 L n^3 L Z :, since the algorithm has to read n^2 elements, which reside on n^2 L cache lines. The same bound can be achieved using a simple (^1) For simplicity in this paper, we use the term “optimal” as a syn-
onym for “asymptotically optimal,” since all our analyses are asymp- totic.
cache-oblivious algorithm that requires no tuning pa- rameters such as the s in BLOCK-MULT. We present such an algorithm, which works on general rectangular matrices, in Section 2. The problems of computing a matrix transpose and of performing an FFT also suc- cumb to remarkably simple algorithms, which are de- scribed in Section 3. Cache-oblivious sorting poses a more formidable challenge. In Sections 4 and 5, we present two sorting algorithms, one based on mergesort and the other on distribution sort, both of which are op- timal in both work and cache misses. The ideal-cache model makes the perhaps- questionable assumptions that there are only two levels in the memory hierarchy, that memory is man- aged automatically by an optimal cache-replacement strategy, and that the cache is fully associative. We address these assumptions in Section 6, showing that to a certain extent, these assumptions entail no loss of generality. Section 7 discusses related work, and Section 8 offers some concluding remarks, including some preliminary empirical results.
This section describes and analyzes a cache-oblivious al- gorithm for multiplying an m n matrix by an n p ma- trix cache-obliviously using Θ 8 mnp :work and incurring Θ 8 m n p 8 mn np mp :
L mnp
L Z : cache misses. These results require the tall-cache assumption (1) for matrices stored in row-major layout format, but the assumption can be relaxed for certain other layouts. We also show that Strassen’s algorithm [31] for multi- plying n n matrices, which uses Θ 8 n lg7^ : work^2 , incurs Θ 81 n^2
L n lg^ L Z : cache misses. In [9] with others, two of the present authors analyzed an optimal divide-and-conquer algorithm for n n ma- trix multiplication that contained no tuning parameters, but we did not study cache-obliviousness per se. That algorithm can be extended to multiply rectangular matri- ces. To multiply a m n matrix A and a n p matrix B , the REC-MULT algorithm halves the largest of the three dimensions and recurs according to one of the following three cases: A 1 A 2
B < A^1 B A 2 B
9 (2)
< A 1 B 1 A 2 B 2 9 (3)
A B 1 B 2 < AB 1 AB 2 (4) In case (2), we have m max n 9 p . Matrix A is split horizontally, and both halves are multiplied by matrix B. In case (3), we have n max m 9 p . Both matrices are (^2) We use the notation lg to denote log 2.
in column-major order (Figure 2(b)), but the assumption that Z < Ω 8 L^2 : can be relaxed for certain other matrix layouts. The s s -blocked layout (Figure 2(c)), for some tuning parameter s , can be used to achieve the same bounds with the weaker assumption that the cache holds at least some sufficiently large constant number of lines. The cache-oblivious bit-interleaved layout (Figure 2(d)) has the same advantage as the blocked layout, but no tuning parameter need be set, since submatrices of size O 8 L : O 8 L : are cache-obliviously stored on O 81 : cache lines. The advantages of bit-interleaved and re- lated layouts have been studied in [11, 12, 16]. One of the practical disadvantages of bit-interleaved layouts is that index calculations on conventional microprocessors can be costly, a deficiency we hope that processor archi- tects will remedy. For square matrices, the cache complexity Q 8 n : < Θ 8 n n^2 L n^3 L Z : of the REC-MULT algorithm is the same as the cache complexity of the cache-aware BLOCK-MULT algorithm and also matches the lower bound by Hong and Kung [21]. This lower bound holds for all algorithms that execute the Θ 8 n^3 : opera- tions given by the definition of matrix multiplication
ci j <
n
k 1
aikbk j
No tight lower bounds for the general problem of matrix multiplication are known. By using an asymptotically faster algorithm, such as Strassen’s algorithm [31] or one of its variants [37], both the work and cache complexity can be reduced. When multiplying n n matrices, Strassen’s algorithm, which is cache oblivious, requires only 7 recursive multiplica- tions of n
2 n
2 matrices and a constant number of matrix additions, yielding the recurrence
Q 8 n :
Θ 81 n n^2
L : if n^2 α Z 9 7 Q 8 n
2 : O 8 n^2
L : otherwise ;
where α is a sufficiently small constant. The solution to this recurrence is Θ 8 n n^2 L n lg^ L Z :.
This section describes a recursive cache-oblivious al- gorithm for transposing an m n matrix which uses O 8 mn : work and incurs O 81 mn
L : cache misses, which is optimal. Using matrix transposition as a sub- routine, we convert a variant [36] of the “six-step” fast Fourier transform (FFT) algorithm [6] into an optimal cache-oblivious algorithm. This FFT algorithm uses O 8 n lg n : work and incurs O 81 ^8 n
L :8^1 log Z n : : cache misses. The problem of matrix transposition is defined as fol- lows. Given an m n matrix stored in a row-major lay- out, compute and store AT^ into an n m matrix B also
stored in a row-major layout. The straightforward algo- rithm for transposition that employs doubly nested loops incurs Θ 8 mn : cache misses on one of the matrices when m Z
L and n Z
L , which is suboptimal. Optimal work and cache complexities can be ob- tained with a divide-and-conquer strategy, however. If n m , the REC-TRANSPOSE algorithm partitions
A < 8 A 1 A 2 : 9 B <
and recursively executes REC-TRANSPOSE 8 A 1 9 B 1 : and REC-TRANSPOSE 8 A 2 9 B 2 :. Otherwise, it divides matrix A horizontally and matrix B vertically and likewise per- forms two transpositions recursively. The next two lem- mas provide upper and lower bounds on the performance of this algorithm.
Lemma 2 The REC-TRANSPOSE algorithm involves O 8 mn : work and incurs O 81 mn
L : cache misses for an m n matrix.
Proof. That the algorithm does O 8 mn : work is straight- forward. For the cache analysis, let Q 8 m 9 n : be the cache complexity of transposing an m n matrix. We as- sume that the matrices are stored in row-major order, the column-major layout having a similar analysis. Let α be a constant sufficiently small such that two submatrices of size m n and n m , where max m 9 n
α L , fit completely in the cache even if each row is stored in a different cache line. We distinguish the three cases.
Case I: max m 9 n
α L. Both the matrices fit in O 81 : 2 mn
L lines. From the choice of α, the number of lines required is at most Z
L. Therefore Q 8 m 9 n :< O 81 mn
L :.
Case II: m
α L n or n
α L m. Suppose first that m
α L n. The REC-TRANSPOSE algorithm divides the greater dimension n by 2 and performs divide and conquer. At some point in the recursion, n falls into the range α L
2
n
α L , and the whole problem fits in cache. Because the layout is row-major, at this point the input array has n rows and m columns, and it is laid out in contiguous locations, requiring at most O 81 nm
L : cache misses to be read. The output array consists of nm elements in m rows, where in the worst case every row lies on a different cache line. Consequently, we incur at most O 8 m nm
L : for writing the output array. Since n α L
2, the total cache complexity for this base case is O 81 m :. These observations yield the recurrence
Q 8 m 9 n :
O 81 m : if n α L
2 9 α L 2 Q 8 m 9 n
2 : O 81 : otherwise ;
whose solution is Q 8 m 9 n : < O 81 mn
L :. The case n
α L m is analogous.
recursion both n and m fall into the range α L
The whole problem fits into cache and can be solved
complexity thus satisfies the recurrence
Theorem 3 The REC-TRANSPOSE algorithm has opti- mal cache complexity.
As an example of an application of this cache- oblivious transposition algorithm, in the rest of this sec- tion we describe and analyze a cache-oblivious algo- rithm for computing the discrete Fourier transform of a complex array of n elements, where n is an exact power of 2. The basic algorithm is the well-known “six-step” variant [6, 36] of the Cooley-Tukey FFT algorithm [13]. Using the cache-oblivious transposition algorithm, how- ever, the FFT becomes cache-oblivious, and its perfor- mance matches the lower bound by Hong and Kung [21]. Recall that the discrete Fourier transform (DFT) of an array X of n complex numbers is the array Y given by
j 0
and 0
i n. Many algorithms evaluate Equation (9) in
ever, we assume that n is an exact power of 2, and we compute Equation (9) according to the Cooley-Tukey al- gorithm, which works recursively as follows. In the base
j 2 0
j 1 0
Observe that both the inner and outer summations in Equation (10) are DFT’s. Operationally, the computa- tion specified by Equation (10) can be performed by computing n 2 transforms of size n 1 (the inner sum), mul-
dle factors [15]), and finally computing n 1 transforms of size n 2 (the outer sum).
recursive step then operates as follows:
Transpose A in place, i.e., use the cache-oblivious REC-TRANSPOSE algorithm to transpose A onto an auxiliary array B , and copy B back onto A. Notice
made up of records containing two elements.
alyze its cache complexity. The algorithm always op- erates on contiguous data, by construction. Thus, by the tall-cache assumption (1), the transposition oper- ations and the twiddle-factor multiplication require at
plexity satisfies the recurrence
problem of size α Z fits in cache. This recurrence has solution
which is optimal for a Cooley-Tukey algorithm, match- ing the lower bound by Hong and Kung [21] when n is an exact power of 2. As with matrix multiplication, no tight lower bounds for cache complexity are known for the general DFT problem.
Cache-oblivious algorithms, like the familiar two-way merge sort, are not optimal with respect to cache misses. The Z -way mergesort suggested by Aggarwal and Vit- ter [3] has optimal cache complexity, but although it ap- parently works well in practice [23], it is cache aware. This section describes a cache-oblivious sorting algo- rithm called “funnelsort.” This algorithm has optimal
at most
cache misses.
into cache. The k -merger has k input queues from
of elements extracted from the i th input queue. Since
available for the input buffers. Lemma 5 applies, whence the total number of cache misses for accessing the input queues is
k
i 1
Similarly, Lemma 4 implies that the cache complexity
its internal data structures. The total cache complexity is
ck^3 log Z k
The base case of the induction consists of values of
quently, a big enough value of c can be found that satis- fies Inequality (12).
the submergers. The “right” merger R is invoked exactly
ements into some buffer. Since k^3 elements are output
follows.
Before invoking R , the algorithm must check every buffer to see whether it is empty. One such check re-
ing to at most k^2 cache misses for all checks. These considerations lead to the recurrence
Application of the inductive hypothesis and the choice
lows:
ck^3 log Z k
ck^3 log Z k
Proof. If n α Z for a small enough constant α, then the algorithm fits into cache. To see why, observe that only one k -merger is active at any time. The biggest
n log Z n
By the tall-cache assumption (1), we have n
holds, and the recurrence simplifies to
The result follows by induction on n. This upper bound matches the lower bound stated by the next theorem, proving that funnelsort is cache- optimal. Theorem 8 The cache complexity of any sorting algo-
Proof. Aggarwal and Vitter [3] show that there is an
misses made by any sorting algorithm on their “out-of- core” memory model, a bound that extends to the ideal- cache model. The theorem can be proved by apply-
In this section, we describe another cache-oblivious op- timal sorting algorithm based on distribution sort. Like the funnelsort algorithm from Section 4, the distribution-
Unlike previous cache-efficient distribution-sorting al- gorithms [1, 3, 25, 34, 36], which use sampling or other techniques to find the partitioning elements before the distribution step, our algorithm uses a “bucket splitting” technique to select pivots incrementally during the dis- tribution step. Given an array A (stored in contiguous locations) of length n , the cache-oblivious distribution sort operates as follows:
(See below for details.)
A stack-based memory allocator is used to exploit spatial locality.
The goal of Step 2 is to distribute the sorted subarrays
tains two invariants. First, at any time each bucket holds
smaller than any element in bucket Bi 1. Second, every bucket has an associated pivot. Initially, only one empty bucket exists with pivot ∞.
The idea is to copy all elements from the subarrays into the buckets while maintaining the invariants. We keep state information for each subarray and bucket. The state of a subarray consists of the index next of the next element to be read from the subarray and the bucket number bnum where this element should be copied. By
been copied. The state of a bucket consists of the pivot and the number of elements currently in the bucket.
We would like to copy the element at position next of a subarray to bucket bnum. If this element is greater than the pivot of bucket bnum , we would increment bnum un- til we find a bucket for which the element is smaller than the pivot. Unfortunately, this basic strategy has poor caching behavior, which calls for a more complicated procedure.
The distribution step is accomplished by the recur-
into buckets starting from B (^) j. Given the precondition
plementation of DISTRIBUTE:
copies all elements from subarray i that belong to
ter the insertion, it can be split into two buckets of size
ministic median-finding algorithm [14, p. 189] followed by a partition.
Lemma 9 The median of n elements can be found
n
Proof. See [14, p. 189] for the linear-time median find- ing algorithm and the work analysis. The cache com- plexity is given by the same recurrence as the work com- plexity with a different base case.
where α is a sufficiently small constant. The result fol- lows.
dition, when a bucket splits, all subarrays whose bnum is greater than the bnum of the split bucket must have their bnum ’s incremented. The analysis of DISTRIBUTE is given by the following lemma.
space to distribute n elements.
Proof. In order to simplify the analysis of the work used by DISTRIBUTE, assume that COPYELEMS uses
the work due to copying elements and splitting of buck- ets separately. The work of DISTRIBUTE is described by
lemma that bounds the effectiveness of the LRU simu- lation. We then show that algorithms whose complex- ity bounds satisfy a simple regularity condition (includ- ing all algorithms heretofore presented) can be ported to caches incorporating an LRU replacement policy.
Lemma 12 Consider an algorithm that causes Q