奇怪的C性能差异?

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

原始代码

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...
    }
}

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

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

解决方法

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

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

1)ICC – 英特尔编译器
2)海湾合作委员会 – 一个很好的第二名
3)MSVC生成代码与其他代码相比可能非常差.

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

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...