ev6-copy_page.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * arch/alpha/lib/ev6-copy_page.S
  3.  *
  4.  * Copy an entire page.
  5.  */
  6. /* The following comparison of this routine vs the normal copy_page.S
  7.    was written by an unnamed ev6 hardware designer and forwarded to me
  8.    via Steven Hobbs <hobbs@steven.zko.dec.com>.
  9.  
  10.    First Problem: STQ overflows.
  11.    -----------------------------
  12. It would be nice if EV6 handled every resource overflow efficiently,
  13. but for some it doesn't.  Including store queue overflows.  It causes
  14. a trap and a restart of the pipe.
  15. To get around this we sometimes use (to borrow a term from a VSSAD
  16. researcher) "aeration".  The idea is to slow the rate at which the
  17. processor receives valid instructions by inserting nops in the fetch
  18. path.  In doing so, you can prevent the overflow and actually make
  19. the code run faster.  You can, of course, take advantage of the fact
  20. that the processor can fetch at most 4 aligned instructions per cycle.
  21. I inserted enough nops to force it to take 10 cycles to fetch the
  22. loop code.  In theory, EV6 should be able to execute this loop in
  23. 9 cycles but I was not able to get it to run that fast -- the initial
  24. conditions were such that I could not reach this optimum rate on
  25. (chaotic) EV6.  I wrote the code such that everything would issue
  26. in order. 
  27.    Second Problem: Dcache index matches.
  28.    -------------------------------------
  29. If you are going to use this routine on random aligned pages, there
  30. is a 25% chance that the pages will be at the same dcache indices.
  31. This results in many nasty memory traps without care.
  32. The solution is to schedule the prefetches to avoid the memory
  33. conflicts.  I schedule the wh64 prefetches farther ahead of the
  34. read prefetches to avoid this problem.
  35.    Third Problem: Needs more prefetching.
  36.    --------------------------------------
  37. In order to improve the code I added deeper prefetching to take the
  38. most advantage of EV6's bandwidth.
  39. I also prefetched the read stream. Note that adding the read prefetch
  40. forced me to add another cycle to the inner-most kernel - up to 11
  41. from the original 8 cycles per iteration.  We could improve performance
  42. further by unrolling the loop and doing multiple prefetches per cycle.
  43.    I think that the code below will be very robust and fast code for the
  44.    purposes of copying aligned pages.  It is slower when both source and
  45.    destination pages are in the dcache, but it is my guess that this is
  46.    less important than the dcache miss case.  */
  47. .text
  48. .align 4
  49. .global copy_page
  50. .ent copy_page
  51. copy_page:
  52. .prologue 0
  53. /* Prefetch 5 read cachelines; write-hint 10 cache lines.  */
  54. wh64 ($16)
  55. ldl $31,0($17)
  56. ldl $31,64($17)
  57. lda $1,1*64($16)
  58. wh64 ($1)
  59. ldl $31,128($17)
  60. ldl $31,192($17)
  61. lda $1,2*64($16)
  62. wh64 ($1)
  63. ldl $31,256($17)
  64. lda $18,118
  65. lda $1,3*64($16)
  66. wh64 ($1)
  67. nop
  68. lda $1,4*64($16)
  69. lda $2,5*64($16)
  70. wh64 ($1)
  71. wh64 ($2)
  72. lda $1,6*64($16)
  73. lda $2,7*64($16)
  74. wh64 ($1)
  75. wh64 ($2)
  76. lda $1,8*64($16)
  77. lda $2,9*64($16)
  78. wh64 ($1)
  79. wh64 ($2)
  80. lda $19,10*64($16)
  81. nop
  82. /* Main prefetching/write-hinting loop.  */
  83. 1: ldq $0,0($17)
  84. ldq $1,8($17)
  85. unop
  86. unop
  87. unop
  88. unop
  89. ldq $2,16($17)
  90. ldq $3,24($17)
  91. ldq $4,32($17)
  92. ldq $5,40($17)
  93. unop
  94. unop
  95. unop
  96. unop
  97. ldq $6,48($17)
  98. ldq $7,56($17)
  99. ldl $31,320($17)
  100. unop
  101. unop
  102. unop
  103. /* This gives the extra cycle of aeration above the minimum.  */
  104. unop
  105. unop
  106. unop
  107. unop
  108. wh64 ($19)
  109. unop
  110. unop
  111. unop
  112. stq $0,0($16)
  113. subq $18,1,$18
  114. stq $1,8($16)
  115. unop
  116. unop
  117. stq $2,16($16)
  118. addq $17,64,$17
  119. stq $3,24($16)
  120. stq $4,32($16)
  121. stq $5,40($16)
  122. addq $19,64,$19
  123. unop
  124. stq $6,48($16)
  125. stq $7,56($16)
  126. addq $16,64,$16
  127. bne $18, 1b
  128. /* Prefetch the final 5 cache lines of the read stream.  */
  129. lda $18,10
  130. ldl $31,320($17)
  131. ldl $31,384($17)
  132. ldl $31,448($17)
  133. ldl $31,512($17)
  134. ldl $31,576($17)
  135. nop
  136. nop
  137. /* Non-prefetching, non-write-hinting cleanup loop for the
  138.    final 10 cache lines.  */
  139. 2: ldq $0,0($17)
  140. ldq $1,8($17)
  141. ldq $2,16($17)
  142. ldq $3,24($17)
  143. ldq $4,32($17)
  144. ldq $5,40($17)
  145. ldq $6,48($17)
  146. ldq $7,56($17)
  147. stq $0,0($16)
  148. subq $18,1,$18
  149. stq $1,8($16)
  150. addq $17,64,$17
  151. stq $2,16($16)
  152. stq $3,24($16)
  153. stq $4,32($16)
  154. stq $5,40($16)
  155. stq $6,48($16)
  156. stq $7,56($16)
  157. addq $16,64,$16
  158. bne $18, 2b
  159. ret
  160. nop
  161. unop
  162. nop
  163. .end copy_page