Advertisement
Guest User

Untitled

a guest
Nov 26th, 2015
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.56 KB | None | 0 0
  1. .globl Ax
  2. Ax:
  3. .LFB0:
  4. # A - rdi
  5. # x - rsi
  6. # b - rdx
  7. # n - rcx
  8.  
  9. # если n <= 0, то выход
  10. testl %ecx, %ecx
  11. jle .L26
  12.  
  13. # x -> rax
  14. movq %rsi, %rax
  15.  
  16. pushq %r15
  17. pushq %r14
  18.  
  19. # rax << 60
  20. salq $60, %rax
  21. # n -> r14
  22. movl %ecx, %r14d
  23. pushq %r13
  24.  
  25. # rax >> 63, получение 4-го байта (2^3 = 8)
  26. # в результате в rax, 1 -- если выравнивание адреса по 8-ми байтам, 0 - по 16
  27. # некоторые команды из SSE работают лишь с выровненными по 16 байт адресами
  28. shrq $63, %rax
  29.  
  30. pushq %r12
  31. pushq %rbp
  32.  
  33. cmpl %ecx, %eax
  34. pushq %rbx
  35.  
  36. # min(n, eax) -> eax
  37. # eax всегда <= 1, а n > 0, поэтому бессмысленная операция
  38. cmova %ecx, %eax
  39.  
  40. cmpl $4, %ecx
  41. # если n <= 4, то n -> eax
  42. cmovbe %ecx, %eax
  43. # r11 = 0
  44. xorl %r11d, %r11d
  45. # ?
  46. movl %eax, %eax
  47. # r14 = n - eax
  48. # в eax - количество элементов, которые будут просчитаны без распараллеливания
  49. # r14 -- количество оставшихся элементов, которые можно попытаться распараллелить
  50. subl %eax, %r14d
  51. # rax -> rbx
  52. movq %rax, %rbx
  53. # rax = 8, если выравнивание по 8 байтам, иначе - 0
  54. salq $3, %rax
  55. # ebp = (r14 - 2)
  56. leal -2(%r14), %ebp
  57. # r13 = адрес первого элемента в векторе x, который можно попытаться распараллелить
  58. leaq (%rsi,%rax), %r13
  59. # rax -> -16(%rsp)
  60. movq %rax, -16(%rsp)
  61. # ebp = [r14 / 2] - 1
  62. shrl %ebp
  63. # ebp = [r14 / 2]
  64. addl $1, %ebp
  65. # r15 = [r14 / 2] * 2
  66. leal (%rbp,%rbp), %r15d
  67. .p2align 4,,10
  68. .p2align 3
  69. .L6:
  70. # ebx - количество элементов, которые нужно просчитать без распараллеливания
  71. testl %ebx, %ebx
  72. # A[i] -> r10
  73. movq (%rdi,%r11,8), %r10
  74. je .L11
  75. # A[i][0] -> xmm0
  76. # sd -> single double
  77. movsd (%r10), %xmm0
  78. cmpl $1, %ebx
  79. movl $1, %r8d
  80. # A[i][0] * x[0] -> xmm0
  81. mulsd (%rsi), %xmm0
  82. # если нужно просчитать лишь один элемент без распараллеливания, то выходим на распараллеливание
  83. je .L8
  84. # аналогично для j = 1, 2, 3
  85. movsd 8(%r10), %xmm1
  86. cmpl $2, %ebx
  87. movl $2, %r8d
  88. mulsd 8(%rsi), %xmm1
  89. addsd %xmm1, %xmm0
  90. je .L8
  91. movsd 16(%r10), %xmm1
  92. cmpl $3, %ebx
  93. movl $3, %r8d
  94. mulsd 16(%rsi), %xmm1
  95. addsd %xmm1, %xmm0
  96. je .L8
  97. movsd 24(%rsi), %xmm1
  98. movl $4, %r8d
  99. mulsd 24(%r10), %xmm1
  100. addsd %xmm1, %xmm0
  101. .L8:
  102. # если количество посчитанных без распараллеливания чисел == n, то идем на следующий шаг (по i)
  103. cmpl %ecx, %ebx
  104. je .L9
  105. .L7:
  106. # в r14 -- количество элементов, которые можно попытаться распараллелить
  107. # если r14 = 1, то сразу переходим на частных случай для нечетного количества
  108. cmpl $1, %r14d
  109. je .L10
  110. # rax = 8, если выравнивание по 8 байтам, иначе - 0
  111. movq -16(%rsp), %rax
  112. # xmm2 = 0
  113. pxor %xmm2, %xmm2
  114. # r9 = 0
  115. xorl %r9d, %r9d
  116. # r12 = &A[i][1], если выравнивание по 8 байтам, иначе - &A[i][0]
  117. leaq (%r10,%rax), %r12
  118. # eax = 0
  119. xorl %eax, %eax
  120.  
  121. .L4:
  122. # Переместить два double (A[i][j], A[i][j + 1]) в xmm1
  123. # apd - aligned packed double, необходимо выравнивание по 16 байтам
  124. movapd (%r12,%rax), %xmm1
  125. # r9 -- количество посчитанных пар
  126. addl $1, %r9d
  127. # в r13 - адрес первого элемента в x для распараллеливания
  128. # умножить A[i][j] * x[j], A[i][j + 1] * x[j + 1]
  129. mulpd 0(%r13,%rax), %xmm1
  130. # j += 2
  131. addq $16, %rax
  132. # ebp -- количество пар
  133. cmpl %r9d, %ebp
  134. # xmm2 + (A[i][j] * x[j], A[i][j + 1] * x[j + 1])
  135. addpd %xmm1, %xmm2
  136. # если посчитали еще не все пары, то считаем дальше
  137. ja .L4
  138. # сложить горизонтально xmm2
  139. haddpd %xmm2, %xmm2
  140. # количество пар * 2 + количество элементов, посчитанных без распараллеливания
  141. addl %r15d, %r8d
  142. # если количество пар * 2 == количество элементов, которые пытались распараллелить, то переходим на следующую итерацию
  143. # иначе, если количество элементов нечетное, то считаем последний отдельно в L9
  144. cmpl %r15d, %r14d
  145. # складываем элементы, посчитанные параллельно и отдельно
  146. addsd %xmm2, %xmm0
  147. je .L9
  148. .L10:
  149. # расширить r8d до r8
  150. movslq %r8d, %r8
  151. # считаем для последнего элемента
  152. movsd (%r10,%r8,8), %xmm1
  153. mulsd (%rsi,%r8,8), %xmm1
  154. addsd %xmm1, %xmm0
  155. .L9:
  156. # перемещаем результат в b[i]
  157. movsd %xmm0, (%rdx,%r11,8)
  158. # i++
  159. addq $1, %r11
  160. # если i < n, то идем на следующую итерацию
  161. cmpl %r11d, %ecx
  162. jg .L6
  163. popq %rbx
  164. popq %rbp
  165. popq %r12
  166. popq %r13
  167. popq %r14
  168. popq %r15
  169. ret
  170. .L11:
  171. xorl %r8d, %r8d
  172. pxor %xmm0, %xmm0
  173. jmp .L7
  174. .L26:
  175. rep ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement