1 / 70

Loop Transformations

Loop Transformations. Motivation Loop level transformations catalogus Loop merging Loop interchange Loop unrolling Unroll-and-Jam Loop tiling Loop Transformation Theory and Dependence Analysis. Thanks for many slides go to the DTSE people from IMEC and

cree
Download Presentation

Loop Transformations

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Loop Transformations • Motivation • Loop level transformations catalogus • Loop merging • Loop interchange • Loop unrolling • Unroll-and-Jam • Loop tiling • Loop Transformation Theory and Dependence Analysis Thanks for many slides go to the DTSE people from IMEC and Dr. Peter Knijnenburg († 2007) from Leiden University

  2. Loop Transformations • Change the order in which the iteration space is traversed. • Can expose parallelism, increase available ILP, or improve memory behavior. • Dependence testing is required to check validity of transformation.

  3. j A i Why loop trafos Example 1: in-place mapping for (j=1; j<M; j++) for (i=0; i<N; i++) A[i][j] = f(A[i][j-1]); for (i=0; i<N; i++) OUT[i] = A[i][M-1]; for (i=1; i<N; i++){ for (j=0; j<M; j++) A[i][j] = f(A[i][j-1]); OUT[i] = A[i][M-1]; } OUT

  4. Foreground memory External memory interface CPU Background memory Why loop trafos Example 2: memory allocation for (i=0; i<N; i++) B[i] = f(A[i]); for (i=0; i<N; i++) C[i] = g(B[i]); for (i=0; i<N; i++){ B[i] = f(A[i]); C[i] = g(B[i]); } N cyc. 2N cyc. N cyc. 2 background ports 1 backgr. + 1 foregr. ports

  5. merge (fusion) improve locality bump extend/reduce body split reverse improve regularity interchange improve locality/regularity skew tiling index split unroll unroll-and-jam Loop transformation catalogue

  6. Loop Merge • Improve locality • Reduce loop overhead for Ia = exp1 to exp2 A(Ia) for Ib = exp1 to exp2 B(Ib) for I = exp1 to exp2 A(I) B(I) 

  7. Location Production/Consumption Consumption(s) Time Location Production/Consumption Consumption(s) Time Loop Merge:Example of locality improvement: Consumptions of second loop closer to productions and consumptions of first loop • Is this always the case after merging loops? for (i=0; i<N; i++) B[i] = f(A[i]); for (j=0; j<N; j++) C[j] = f(B[j],A[j]); for (i=0; i<N; i++) B[i] = f(A[i]); C[i] = f(B[i],A[i]);

  8. Loop Merge not always allowed ! • Data dependencies from first to second loopcan block Loop Merge • Merging is allowed if  I: cons(I) in loop 2  prod(I) in loop 1 • Enablers: Bump, Reverse, Skew for (i=0; i<N; i++) B[i] = f(A[i]); for (i=0; i<N; i++) C[i] = g(B[N-1]); for (i=0; i<N; i++) B[i] = f(A[i]); for (i=2; i<N; i++) C[i] = g(B[i-2]); N-1 >= i i-2 < i

  9. Loop Bump for I = exp1 to exp2 A(I)  for I = exp1+N to exp2+N A(I-N)

  10. Loop Bump: Example as enabler for (i=2; i<N; i++) B[i] = f(A[i]); for (i=0; i<N-2; i++) C[i] = g(B[i+2]); i+2 > i  merging not possible Loop Bump for (i=2; i<N; i++) B[i] = f(A[i]); for (i=2; i<N; i++) C[i-2] = g(B[i+2-2]);  i+2–2 = i  merging possible for (i=2; i<N; i++) B[i] = f(A[i]); C[i-2] = g(B[i]); Loop Merge 

  11. Loop Extend for I = exp1 to exp2 A(I) exp3 exp1 exp4 exp2  for I = exp3 to exp4 if Iexp1and Iexp2 A(I)

  12. Loop Extend: Example as enabler for (i=0; i<N; i++) B[i] = f(A[i]); for (i=2; i<N+2; i++) C[i-2] = g(B[i]); for (i=0; i<N+2; i++) if(i<N) B[i] = f(A[i]); for (i=0; i<N+2; i++) if(i>=2) C[i-2] = g(B[i); Loop Extend  for (i=0; i<N+2; i++) if(i<N) B[i] = f(A[i]); if(i>=2) C[i-2] = g(B[i); Loop Merge 

  13. Loop Reduce for I = exp1 to exp2 if Iexp3and Iexp4 A(I)  for I = max(exp1,exp3) to min(exp2,exp4) A(I)

  14. Loop Body Split A(I) must be single-assignment: its elements should be written once for I = exp1 to exp2 A(I) B(I) for Ia = exp1 toexp2 A(Ia) for Ib = exp1 to exp2 B(Ib) 

  15. Loop Body Split: Example as enabler for (i=0; i<N; i++) A[i] = f(A[i-1]); B[i] = g(in[i]); for (j=0; j<N; j++) C[i] = h(B[i],A[N]);  Loop Body Split for (i=0; i<N; i++) A[i] = f(A[i-1]); for (k=0; k<N; k++) B[k] = g(in[k]); for (j=0; j<N; j++) C[j] = h(B[j],A[N]); for (i=0; i<N; i++) A[i] = f(A[i-1]); for (j=0; j<N; j++) B[j] = g(in[j]); C[j] = h(B[j],A[N]);  Loop Merge

  16. Location Production Consumption Time Location Time Loop Reverse for I = exp1 to exp2 A(I) for I = exp2downto exp1 A(I)  OR for I = exp1 to exp2 A(exp2-(I-exp1))

  17. Loop Reverse: Satisfy dependencies No loop-carried dependencies allowed ! A[0] = … for (i=1; i<N; i++) A[i] = f(A[i-1]); A[0] = … for (i=1; i<=N; i++) A[i]= A[i-1]+ f(…); Enabler: data-flow transformations (+ is associative) A[N] = … for (i=N-1; i>=0; i--) A[i]= A[i+1]+ f(…);

  18. Loop Reverse: Example as enabler for (i=0; i<=N; i++) B[i] = f(A[i]); for (i=0; i<=N; i++) C[i] = g(B[N-i]); N–i > i  merging not possible Loop Reverse for (i=0; i<=N; i++) B[i] = f(A[i]); for (i=0; i<=N; i++) C[N-i] = g(B[N-(N-i)]);  N-(N-i) = i  merging possible Loop Merge  for (i=0; i<=N; i++) B[i] = f(A[i]); C[N-i] = g(B[i]);

  19. Loop Interchange for I1 = exp1 to exp2 for I2 = exp3 to exp4 A(I1, I2) for I2 = exp3 to exp4 for I1 = exp1 to exp2 A(I1, I2) 

  20. Loop Interchange: index traversal j j Loop Interchange i i for(i=0; i<W; i++) for(j=0; j<H; j++) A[i][j] = …; for(j=0; j<H; j++) for(i=0; i<W; i++) A[i][j] = …;

  21. Loop Interchange • Validity: check dependence direction vectors. • Mostly used to improve cache behavior. • The innermost loop (loop index changes fastest) should (only) index the right-most array index expression in case of row-major storage, like in C. • Can improve execution time by 1 or 2 orders of magnitude.

  22. Loop Interchange (cont’d) • Loop interchange can also expose parallelism. • If an inner-loop does not carry a dependence (entry in direction vector equals ‘=‘), this loop can be executed in parallel. • Moving this loop outwards increases the granularity of the parallel loop iterations.

  23. Loop Interchange:Example of locality improvement • In second loop: • A[j] reused N times (temporal locality) • However: loosing spatial locality in B (assuming row major ordering) • => Exploration required for (i=0; i<N; i++) for (j=0; j<M; j++) B[i][j] = f(A[j],B[i][j-1]); for (j=0; j<M; j++) for (i=0; i<N; i++) B[i][j] = f(A[j],B[i][j-1]);

  24. Loop Interchange: Satisfy dependencies • No loop-carried dependencies allowedunless  I2: prod(I2)  cons(I2) for (i=0; i<N; i++) for (j=0; j<M; j++) A[i][j] = f(A[i-1][j+1]); for (i=0; i<N; i++) for (j=0; j<M; j++) A[i][j] = f(A[i-1][j]); • Enablers: • Data-flow transformations • Loop Bump

  25. Loop Skew:Basic transformation for I1 = exp1 to exp2 for I2 = exp3 to exp4 A(I1, I2) for I1 = exp1 to exp2 for I2 = exp3+.I1+ to exp4+.I1+ A(I1, I2-.I1-) for I1 = exp1 to exp2 for I2 = exp3+.I1+ to exp4+.I1+ A(I1, I2-.I1-) 

  26. j j i i Loop Skew Loop Skewing for(j=0;j<H;j++) for(i=0;i<W;i++) A[i][j] = ...; for(j=0; j<H; j++) for(i=0+j; i<W+j;i++) A[I-j][j] = ...;

  27. Loop Extend & Interchange  Loop Skew: Example as enabler of regularity improvement for (i=0; i<N; i++) for (j=0; j<M; j++) … = f(A[i+j]); for (i=0; i<N; i++) for (j=i; j<i+M; j++) … = f(A[j]); Loop Skew  for (j=0; j<N+M; j++) for (i=0; i<N; i++) if (j>=i && j<i+M) … = f(A[j]);

  28. Loop Tiling for I = 0 to exp1 . exp2 A(I) Tile size exp1 Tile factor exp2 for I1 = 0 to exp2 for I2 = exp1.I1 to exp1.(I1 +1) A(I2) 

  29. Loop Tiling i Loop Tiling j i for(i=0;i<9;i++) A[i] = ...; for(j=0; j<3; j++) for(i=4*j; i<4*j+4; i++) if (i<9) A[i] = ...;

  30. Loop Tiling • Improve cache reuse by dividing the iteration space into tiles and iterating over these tiles. • Only useful when working set does not fit into cache or when there exists much interference. • Two adjacent loops can legally be tiled if they can legally be interchanged.

  31. for(i=0; i<N; i++) for(j=0; j<N; j++) A[i][j] = B[j][i]; 2-D Tiling Example for(TI=0; TI<N; TI+=16) for(TJ=0; TJ<N; TJ+=16) for(i=TI; i<min(TI+16,N); i++) for(j=TJ; j<min(TJ+16,N); j++) A[i][j] = B[j][i];

  32. 2-D Tiling • Show index space traversal

  33. What is the best Tile Size? • Current tile size selection algorithms use a cache model: • Generate collection of tile sizes; • Estimate resulting cache miss rate; • Select best one. • Only take into account L1 cache. • Mostly do not take into account n-way associativity.

  34. Loop Index Split for Ia = exp1 to exp2 A(Ia) for Ia = exp1 top A(Ia) for Ib = p+1 to exp2 A(Ib) 

  35. Loop Unrolling • Duplicate loop body and adjust loop header. • Increases available ILP, reduces loop overhead, and increases possibilities for common subexpression elimination. • Always valid !!

  36. (Partial) Loop Unrolling for I = exp1 to exp2 A(I) A(exp1) A(exp1+1) A(exp1+2) … A(exp2) for I = exp1/2 to exp2 /2 A(2l) A(2l+1) 

  37. Loop Unrolling: Downside • If unroll factor is not divisor of trip count, then need to add remainder loop. • If trip count not known at compile time, need to check at runtime. • Code size increases which may result in higher I-cache miss rate. • Global determination of optimal unroll factors is difficult.

  38. Loop Unroll: Example of removal of non-affine iterator for (L=1; L < 4; L++) for (i=0; i < (1<<L); i++) A(L,i); for (i=0; i < 2; i++) A(1,i); for (i=0; i < 4; i++) A(2,i); for (i=0; i < 8; i++) A(3,i);

  39. Unroll-and-Jam • Unroll outerloop and fuse new copies of the innerloop. • Increases size of loop body and hence available ILP. • Can also improve locality.

  40. Unroll-and-Jam Example • More ILP exposed • Spatial locality of B enhanced for (i=0;i<N;i++) for (j=0;j<N;j++) A[i][j] = B[j][i]; for (i=0;i<N;i++) for (j=0;j<N;j++) A[i][j] = B[j][i]; for (j=0;j<N;j++) A[i+1][j] = B[j][i+1]; for (i=0; i<N; i+=2) for (j=0; j<N; j++) { A[i][j] = B[j][i]; A[i+1][j] = B[j][i+1]; }

  41. Simplified loop transformation script • Give all loops same nesting depth • Use dummy 1-iteration loops if necessary • Improve regularity • Usually applying loop interchange or reverse • Improve locality • Usually applying loop merge • Break data dependencies with loop bump/skew • Sometimes loop index split or unrolling is easier

  42. Loop transformation theory • Iteration spaces • Polyhedral model • Dependency analysis

  43. Technical Preliminaries (1) do i = 2, N do j = i, N x[i,j]=0.5*(x[i-1,j]+ x[i,j-1]) enddo (1) j • Address expr (1) 4 • perfect loop nest • iteration space • dependence vector 3 2 i 2 3 4

  44. Technical Preliminaries (2) Switch loop indexes: do m = 2, N do n = 2, m x[n,m]=0.5*(x[n-1,m]+ x[n,m-1]) enddo (2) (2) affine transformation

  45. Polyhedral Model • Polyhedron is set x : Ax  cfor some matrix A and bounds vector c • Polyhedra (or Polytopes) are objects in a many-dimensional space without holes • Iteration spaces of loops (with unit stride) can be represented as polyhedra • Array accesses and loop transformations can be represented as matrices

  46. Iteration Space • A loop nest is represented as BI  b for iteration vector I • Example: for(i=0; i<10;i++) -1 0 0 for(j=i; j<10;j++) 1 0 i 9 1 -1 j 0 0 1 9 

  47. Array Accesses • Any array access A[e1][e2] for linear index expressions e1 and e2 can be represented as an access matrix and offset vector. A + a • This can be considered as a mapping from the iteration space into the storage space of the array (which is a trivial polyhedron)

  48. Unimodular Matrices • A unimodular matrix T is a matrix with integer entries and determinant 1. • This means that such a matrix maps an object onto another object with exactly the same number of integer points in it. • Its inverse T¹ always exist and is unimodular as well.

  49. Types of Unimodular Transformations • Loop interchange • Loop reversal • Loop skewing for arbitrary skew factor • Since unimodular transformations are closed under multiplication, any combination is a unimodular transformation again.

  50. Application • Transformed loop nest is given by AT¹ I’  a • Any array access matrix is transformed into AT¹. • Transformed loop nest needs to be normalized by means of Fourier-Motzkin elimination to ensure that loop bounds are affine expressions in more outer loop indices.

More Related