所以即使是汇编代码中的总菜鸟也要阅读它们
所以我有一个简单的c代码
void saxpy()
{
for(int i = 0; i < ARRAY_SIZE; i++) {
float product = a*x[i];
z[i] = product + y[i];
}
}
以及使用
编译时的等效汇编代码gcc -std=c99 -O3 -fno-tree-vectorize -S code.c -o code-O3.s
给我以下的asssembly代码
saxpy:
.LFB0:
.cfi_startproc
movss a(%rip), %xmm1
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movss x(%rax), %xmm0
addq $4, %rax
mulss %xmm1, %xmm0
addss y-4(%rax), %xmm0
movss %xmm0, z-4(%rax)
cmpq $262144, %rax
jne .L3
rep ret
.cfi_endproc
我明白循环展开已经发生了 但我无法理解背后的意图和想法
addq $4, %rax
mulss %xmm1, %xmm0
addss y-4(%rax), %xmm0
movss %xmm0, z-4(%rax)
有人可以解释,使用4,和 这些陈述意味着什么 y-4(%rax)
答案 0 :(得分:1)
x
,y
和z
是全局数组。您遗漏了列表中声明符号的末尾。
I put your code on godbolt for you,定义了必要的全局变量(并修复了缩进)。看看底部。
顺便说一下,这里没有展开。每个标量单精度mul都有一个并加入循环。尝试使用-funroll-loops
查看它展开。
With -march=haswell
, gcc will use an FMA instruction。如果你通过省略-fno-tree-vectorize
来解除编译器的瘫痪,并且#define ARRAY_SIZE
很小,比如100,它会完全展开循环,主要是32byte FMA ymm指令,以16byte FMA xmm结束。
此外,需要向rax寄存器添加立即值4。 根据声明&#34; addq $ 4,%rax&#34;
完成
循环将指针递增4个字节,而不是使用缩放索引寻址模式。
查看https://stackoverflow.com/questions/tagged/x86上的链接。此外,使用调试器单步执行代码通常是确保您了解其执行情况的好方法。