由于fpu操作非常昂贵,我希望尽量少使用fpu操作。同时,我想知道浮点变量中的哪种操作会被算作fpu涉及的操作?
如下面的代码会涉及fpu单元吗?
struct my_float_struct {
int f;
} g;
void func(float a)
{
g.f = a;
}
调用func会导致延迟FPU上下文切换吗?
答案 0 :(得分:0)
在内核中,你根本不应该使用float
(使用lookup tables并乘以系数来节省除法运算的精度)。在用户空间中,RHS上涉及float
类型的所有操作都将导致FPU指令使用。如果在RHS上有2个整数但是将结果赋值给浮点数(在LHS上) - 你将最终得到整数运算,但也会转换为浮点指令(如
cvtsi2ss
)。
实际上很容易回答您的问题,只需查看相应C代码的反汇编。
C代码(使用gcc -Wall -O0 -g main.c
构建):
int main(void)
{
volatile float f1, f2;
volatile int i;
f1 = i * 356;
f2 = f1 * f2;
return 0;
}
反汇编(使用objdump -DS a.out
):
int main(void)
{
4004b6: 55 push %rbp
4004b7: 48 89 e5 mov %rsp,%rbp
volatile float f1, f2;
volatile int i;
f1 = i * 356;
4004ba: 8b 45 f4 mov -0xc(%rbp),%eax
4004bd: 69 c0 64 01 00 00 imul $0x164,%eax,%eax
4004c3: 66 0f ef d2 pxor %xmm2,%xmm2
4004c7: f3 0f 2a d0 cvtsi2ss %eax,%xmm2
4004cb: 66 0f 7e d0 movd %xmm2,%eax
4004cf: 89 45 fc mov %eax,-0x4(%rbp)
f2 = f1 * f2;
4004d2: f3 0f 10 4d fc movss -0x4(%rbp),%xmm1
4004d7: f3 0f 10 45 f8 movss -0x8(%rbp),%xmm0
4004dc: f3 0f 59 c8 mulss %xmm0,%xmm1
4004e0: 66 0f 7e c8 movd %xmm1,%eax
4004e4: 89 45 f8 mov %eax,-0x8(%rbp)
return 0;
4004e7: b8 00 00 00 00 mov $0x0,%eax
}
从这里你可以看到:
基本上你可以立即看到指令涉及的FPU是否在FPU寄存器上运行,如%xmm0
,%xmm1
等。