浮动分配是否计为使用fpu?

时间:2015-04-09 07:43:49

标签: linux context-switch fpu

由于fpu操作非常昂贵,我希望尽量少使用fpu操作。同时,我想知道浮点变量中的哪种操作会被算作fpu涉及的操作?

如下面的代码会涉及fpu单元吗?

struct my_float_struct {
    int f;
} g;

void func(float a)
{
    g.f = a;
}

调用func会导致延迟FPU上下文切换吗?

1 个答案:

答案 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
}

从这里你可以看到:

  • 当整数乘以整数,但将结果赋给float时,它会导致imul指令(整数乘法),但也导致cvtsi2ss(转换为float)指令。
  • 当乘以2个浮点数时,它会导致mulss指令,浮动乘以

基本上你可以立即看到指令涉及的FPU是否在FPU寄存器上运行,如%xmm0%xmm1等。