待编辑
原始代码
取自深入理解计算机系统p182页,这里使用了在线编译器Compiler Explorer(强烈推荐,可以实时看汇编代码,网址Compiler Explorer (godbolt.org)
)
#define N 16
typedef int fix_martrix[N][N];
int fix_prod_ele(fix_martrix A,fix_martrix B,long i,long k)
{
long j;
int result =0;
for (j=0;j<N;++j){
result+=A[i][j]*B[j][k];
}
return result;
}
未优化时,即使用-Og的汇编代码
fix_prod_ele(int (*) [16], int (*) [16], long, long):
movq %rdi, %r9
movq %rsi, %r10
movq %rdx, %r8
movq %rcx, %rdi
movl $0, %esi
movl $0, %eax
jmp .L3
.L4:
movq %r8, %rcx
salq $6, %rcx
addq %r9, %rcx
movq %rax, %rdx
salq $6, %rdx
addq %r10, %rdx
movl (%rdx,%rdi,4), %edx ;注意这里和下面使用了乘法指令伸缩,在一些处理器中会招致严重的性能处罚
imull (%rcx,%rax,4), %edx
addl %edx, %esi
addq $1, %rax
.L3:
cmpq $15, %rax
jle .L4
movl %esi, %eax
ret
使用-O1优化后代码
fix_prod_ele(int (*) [16], int (*) [16], long, long):
salq $6, %rdx
addq %rdx, %rdi
leaq (%rsi,%rcx,4), %rax
leaq 1024(%rax), %rsi
movl $0, %ecx
.L2:
movl (%rdi), %edx
imull (%rax), %edx
addl %edx, %ecx
addq $4, %rdi ;优化后的寻址使用了加法和立即数来寻址,更快
addq $64, %rax
cmpq %rsi, %rax
jne .L2
movl %ecx, %eax
ret