奇怪的C++性能差异?

6 c++ optimization performance

我只是偶然发现了一个似乎具有违反直觉性能影响的变化.任何人都可以为这种行为提供可能的解释吗?

原始代码:

for (int i = 0; i < ct; ++i) {
    // do some stuff...

    int iFreq = getFreq(i);
    double dFreq = iFreq;

    if (iFreq != 0) {
        // do some stuff with iFreq...
        // do some calculations with dFreq...
    }
}
Run Code Online (Sandbox Code Playgroud)

在"性能传递"期间清理此代码时,我决定移动块dFreq内部的定义if,因为它只在内部使用if.有涉及多个计算dFreq,所以我为它保存多个运行时转换从成本并没有完全消除它intdouble.我预计没有任何性能差异,或者如果有的话,可以忽略不计的改进.然而,性能下降了近10%.我已经多次测量过,这确实是我做过的唯一改变.上面显示的代码片段在几个其他循环内执行.我在运行中获得非常一致的时序,并且可以肯定地确认我所描述的变化会使性能降低约10%.我期望的性能提高,因为intdouble转换只会发生时iFreq != 0.

中断代码:

for (int i = 0; i < ct; ++i) {
    // do some stuff...

    int iFreq = getFreq(i);

    if (iFreq != 0) {
        // do some stuff with iFreq...
        double dFreq = iFreq;
        // do some stuff with dFreq...
    }
}
Run Code Online (Sandbox Code Playgroud)

有谁能解释一下?我正在使用带有/ O2的VC++ 9.0.我只是想了解我在这里没有考虑的问题.

phk*_*ler 7

在使用iFreq进行计算之前,您应该立即将转换放入if()中的dFreq.如果指令在代码中更远,则转换可以与整数计算并行执行.一个好的编译器可能能够将它推得更远,而一个不那么好的编译器可能会把它放在它落到的地方.由于您将其移动到整数计算之后,它可能无法与整数代码并行运行,从而导致速度减慢.如果它确实并行运行,那么取决于CPU(发出FP指令,其结果从未使用过,对原始版本影响不大)可能几乎没有任何改进.

如果你真的想要提高性能,许多人已经做了基准测试并按以下顺序对以下编译器进行排名:

1)ICC - 英特尔编译器2)GCC - 良好的第二位3)MSVC生成的代码与其他代码相比可能相当差.

如果有的话,您可能还想尝试-O3.


Mar*_*ner 6

也许结果getFreq是在第一种情况下保存在寄存器中并在第二种情况下写入存储器?也可能是,性能下降与CPU机制有关,如流水线和/或分支预测.您可以检查生成的汇编代码.