微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

奇怪的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.

原文地址:https://www.jb51.cc/c/117802.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐