我可以创建一个带有传递给C ++函数的形式参数的联合吗?

时间:2011-10-26 16:04:28

标签: c++ function parameters unions absolute-value

下面的函数计算32位浮点值的绝对值:

__forceinline static float Abs(float x)
{
    union {
        float x;
        int a;
    } u;
    //u.x = x;
    u.a &= 0x7FFFFFFF;
    return u.x;
}

在函数中声明的union你持有变量x,它与在函数中作为参数传递的x不同。有没有办法用函数的参数创建一个联合 - x?

任何原因上面的函数与未注释的行执行的时间比这个更长?

__forceinline float fastAbs(float a)
{
    int b= *((int *)&a) & 0x7FFFFFFF;
    return *((float *)(&b));
}

我正试图找出以尽可能少的读/写内存计数来获取浮点值Abs的最佳方法。

2 个答案:

答案 0 :(得分:5)

答案 1 :(得分:2)

查看在发布模式下编译的代码的反汇编,差异非常明显! 我删除了内联并使用了两个虚函数,以允许编译器不进行太多优化,让我们显示差异。

这是第一个功能。

013D1002  in          al,dx  
            union {
                float x;
                int a;
            } u;
            u.x = x;
013D1003  fld         dword ptr [x]   // Loads a float on top of the FPU STACK.
013D1006  fstp        dword ptr [x]   // Pops a Float Number from the top of the FPU Stack into the destination address.
            u.a &= 0x7FFFFFFF;
013D1009  and         dword ptr [x],7FFFFFFFh  // Execute a 32 bit binary and operation with the specified address.
            return u.x;
013D1010  fld         dword ptr [x]  // Loads the result on top of the FPU stack.
        }

这是第二个功能。

013D1020  push        ebp                       // Standard function entry... i'm using a virtual function here to show the difference.
013D1021  mov         ebp,esp
            int b= *((int *)&a) & 0x7FFFFFFF;
013D1023  mov         eax,dword ptr [a]         // Load into eax our parameter.
013D1026  and         eax,7FFFFFFFh             // Execute 32 bit binary and between our register and our constant.
013D102B  mov         dword ptr [a],eax         // Move the register value into our destination variable
            return *((float *)(&b));
013D102E  fld         dword ptr [a]             // Loads the result on top of the FPU stack.

第一种情况下浮点运算的数量和FPU堆栈的使用量更大。 功能正在执行你所要求的,所以毫不奇怪。 所以我希望第二个功能更快。

现在......删除虚拟和内联的东西有点不同,这里很难编写反汇编代码,因为当然编译器做得很好,但我再说一遍,如果值不是常量,编译器将使用第一个函数中的浮点运算更多。 当然,整数运算比浮点运算更快。

你确定直接使用math.h abs函数比你的方法慢吗? 如果正确内联,abs函数就会这样做!

00D71016  fabs  

在长代码中很难看到像这样的微优化,但是如果在长链浮点运算中调用函数,那么fab将更好地工作,因为值已经存在于FPU堆栈或SSE寄存器中! abs会更快,更好地由编译器优化。

你无法衡量在一段代码中运行循环的优化的性能,你必须看到编译器如何在实际代码中混合在一起。