C/C++:乘以或位移然后分割?

前端之家收集整理的这篇文章主要介绍了C/C++:乘以或位移然后分割?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这个问题在这里已经有一个答案:> Is multiplication and division using shift operators in C actually faster?14个
可以这样做的时候,我想知道用一个位移替换单个乘法后跟一个整数除法是否更快.说我有一个int k,我想要乘以2.25.

什么更快?

int k = 5;
k *= 2.25;
std::cout << k << std::endl;

要么

int k = 5;
k = (k<<1) + (k/4);
std::cout << k << std::endl;

产量

11
11

两者都给出相同的结果,可以查看this full example.

解决方法

第一次尝试

我定义函数regularmultiply()和bitwisemultiply(),如下所示:

int regularmultiply(int j)
{
    return j * 2.25;
}

int bitwisemultiply(int k)
{
    return (k << 1) + (k >> 2);
}

在使用仪器进行分析时(在2009年Macbook OS X 10.9.2中的XCode中),似乎比常规执行的速度要快两倍.

汇编代码输出似乎证实了这一点,因为大部分时间花费大部分时间用于注册改组和函数返回,而常规的大部分时间都花费在乘法上.

regularmultiply:

bitwisemultiply:

但我的审判时间太短.

第二次尝试

接下来,我尝试使用1000万次乘法执行这两个函数,这次将循环放在函数中,以便所有的函数进入和离开都不会掩盖数字.而这一次,结果是每个方法花了大约52毫秒的时间.因此,至少对于相对较大而不是巨大的计算量,这两个功能大致相同.这让我感到惊讶,所以我决定计算更长和更大的数字.

第三次尝试

这一次,我只有1亿,通过5亿加倍2.25,但比特比实际上出来比普通比较慢.

最后的尝试

最后,我切换了这两个功能的顺序,只是为了看看Instrument中不断增长的cpu图表可能会减慢第二个功能.但是,经常性的表现略好一些:

这是最后的程序是什么样的:

#include <stdio.h>

int main(void)
{
    void regularmultiplyloop(int j);
    void bitwisemultiplyloop(int k);

    int i,j,k;

    j = k = 4;
    bitwisemultiplyloop(k);
    regularmultiplyloop(j);

    return 0;
}

void regularmultiplyloop(int j)
{
    for(int m = 0; m < 10; m++)
    {
        for(int i = 100000000; i < 500000000; i++)
        {
            j = i;
            j *= 2.25;
        }
        printf("j: %d\n",j);
    }
}

void bitwisemultiplyloop(int k)
{
    for(int m = 0; m < 10; m++)
    {
        for(int i = 100000000; i < 500000000; i++)
        {
            k = i;
            k = (k << 1) + (k >> 2);
        }
        printf("k: %d\n",k);
    }
}

结论

那么我们可以说这一切呢?有一点我们可以肯定地说,优化编译器比大多数人更好.此外,当有很多计算时,这些优化显示出更多的优势,这是您真正想要优化的唯一时间.因此,除非您在汇编中编码优化,否则将乘法更改为位移可能不会有太大帮助.

考虑应用程序的效率总是很好,但微型效率的提高通常不足以保证您的代码不易读取.

猜你在找的C&C++相关文章