1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
| #/* $begin ncopy-ys */ ################################################################## # ncopy.ys - Copy a src block of len words to dst. # Return the number of positive words (>0) contained in src. # # name: He Zhuoyuan # id: 1800013351@pku.edu.cn # # Describe how and why you modified the baseline code. # 1. 增加iaddq指令,使得很多两步指令可以合并为一布 # 2. 一开始的%rax就是0,不需要赋值 # 3. n * 1循环展开,减少循环的次数,减少浪费CPE的跳转指令,同时减少load/use造成的bubble # 4. 跳转指令是默认taken的,所以要把概率高的下一步语句写在跳转的目标位置 # 5. 处理最后的小于n个元素时,尽量平衡各个情况所需的CPE(参考了三叉树的实现方式) # 6. 想办法减少len较小的时候的判断用的额外开销,因为此时必要开销仅仅会分摊到很少的几个数,因此对总平均CPE影响很大 # 7. 为了减少代码长度,在处理最后小于n个数的时候想办法复用代码(通过不改变条件码来决定是否跳转,并且此步骤本来应该是bubble,不增加CPE) ################################################################## # Do not modify this portion # Function prologue. # %rdi = src, %rsi = dst, %rdx = len ncopy:
################################################################## # You can modify this portion # Loop header L0: iaddq $-10,%rdx jl LASTN # 处理最后小于n个数
L1: # 对10个数两个一组处理,避免load/use气泡 mrmovq (%rdi), %r8 mrmovq 8(%rdi),%r9 rmmovq %r8,(%rsi) andq %r8, %r8 jle L2 iaddq $1,%rax # if (val > 0) count++ L2: rmmovq %r9,8(%rsi) andq %r9,%r9 jle L3 iaddq $1,%rax L3: mrmovq 16(%rdi), %r8 mrmovq 24(%rdi), %r9 rmmovq %r8,16(%rsi) andq %r8, %r8 jle L4 iaddq $1, %rax # if (val > 0) count++ L4: rmmovq %r9,24(%rsi) andq %r9,%r9 jle L5 iaddq $1,%rax L5: mrmovq 32(%rdi), %r8 mrmovq 40(%rdi), %r9 rmmovq %r8,32(%rsi) andq %r8, %r8 jle L6 iaddq $1, %rax # if (val > 0) count++ L6: rmmovq %r9,40(%rsi) andq %r9,%r9 jle L7 iaddq $1,%rax L7: mrmovq 48(%rdi), %r8 mrmovq 56(%rdi), %r9 rmmovq %r8,48(%rsi) andq %r8, %r8 jle L8 iaddq $1, %rax # if (val > 0) count++ L8: rmmovq %r9,56(%rsi) andq %r9,%r9 jle L9 iaddq $1,%rax L9: mrmovq 64(%rdi), %r8 mrmovq 72(%rdi), %r9 rmmovq %r8,64(%rsi) andq %r8, %r8 jle L10 iaddq $1, %rax # if (val > 0) count++ L10: rmmovq %r9,72(%rsi) andq %r9,%r9 jle L11 iaddq $1,%rax # if (val > 0) count++
L11: # next loop preparation iaddq $80,%rdi iaddq $80,%rsi iaddq $-10,%rdx jge L1
LASTN: mrmovq (%rdi), %r10 iaddq $7,%rdx # 判断剩余的len与3(10-7)的大小关系 jl LESS3 # <3 jg MORE3 # >3 je EQUAL3 # =3
LESS3: iaddq $2,%rdx # 10-7-2=1 je LAST1_2 iaddq $-1,%rdx # len == 2 je LAST2 ret # len == 0 MORE3: iaddq $-3,%rdx # 10-7+3=6 jg MORE6 # len > 6 je EQUAL6 # len == 6 iaddq $1,%rdx jl LAST4 # len == 4 je LAST5 # len == 5 MORE6: iaddq $-2,%rdx jl LAST7 mrmovq 64(%rdi), %r9 # read src[8] from src je LAST8 # len=8
LAST9: rmmovq %r9, 64(%rsi) andq %r9, %r9 # set cc
LAST8: mrmovq 56(%rdi), %r8 # read src[7] from src jle LAST8_2 iaddq $1, %rax # if(rsi[8]>0) count++ LAST8_2: rmmovq %r8, 56(%rsi) andq %r8, %r8 # set cc
LAST7: mrmovq 48(%rdi), %r8 # read src[6] from src jle LAST7_2 iaddq $1, %rax # if(rsi[7]>0) count++ LAST7_2: rmmovq %r8, 48(%rsi) andq %r8, %r8 # set cc
EQUAL6: mrmovq 40(%rdi), %r8 # read src[5] from src jle LAST6_2 iaddq $1, %rax # if(rsi[6]>0) count++ LAST6_2: rmmovq %r8, 40(%rsi) andq %r8, %r8 # set cc
LAST5: mrmovq 32(%rdi), %r8 # read src[4] from src jle LAST5_2 iaddq $1, %rax # if(rsi[5]>0) count++ LAST5_2: rmmovq %r8, 32(%rsi) andq %r8, %r8 # set cc
LAST4: mrmovq 24(%rdi), %r8 # read src[3] from src jle LAST4_2 iaddq $1, %rax # if(rsi[4]>0) count++ LAST4_2: rmmovq %r8, 24(%rsi) andq %r8, %r8 # set cc
EQUAL3: mrmovq 16(%rdi), %r8 # read src[2] from src jle EQUAL3_2 iaddq $1, %rax # if(rsi[3]>0) count++ EQUAL3_2: rmmovq %r8, 16(%rsi) andq %r8, %r8 # set cc
LAST2: mrmovq 8(%rdi), %r8 # read src[1] from src jle LAST2_2 iaddq $1, %rax # if(rsi[2]>0) count++ LAST2_2: rmmovq %r8, 8(%rsi) andq %r8, %r8
LAST1: # mrmovq (%rdi), %r8 # read src[0] from src jle LAST1_2 # 上一步操作(如果是跳转到这里执行直接跳转,不然判断上一个记录到dst的数是不是正数) iaddq $1, %rax # if(rsi[1]>0) count++ LAST1_2: rmmovq %r10, (%rsi) andq %r10, %r10 jle Done iaddq $1, %rax # if(rsi[0]>0) count++
################################################################## # Do not modify the following section of code # Function epilogue. Done: ret ################################################################## # Keep the following label at the end of your function End: #/* $end ncopy-ys */
|