艾路起 2021-05-25 11:52 采纳率: 100%
浏览 23
已采纳

为什么是去分支反而运行速度变慢了

int main()
{
    clock_t startTime, endTime;
    for (int s = 0; s < 100; s++)
    {
        int number[100];
        for (int i = 0; i < 100; i++)
        { 
            number[i]= (rand() % 100);
        }

        {
            
            int unm = 0;
            int max = 0;
            startTime = clock();
            for (int i = 0; i < 123456789; i++)
            {
                unm = (number[i%100] - 50) >> 31;
                max = (number[i % 100] & unm) + max;
            }
            endTime = clock();
            printf("优化CPU时间:%d tick 结果%d", endTime - startTime,max);
        }

        {
          
            int unm = 0;
            int max = 0;
            startTime = clock();
            for (int i = 0; i < 123456789; i++)
            {

                if (number[i % 100] < 50)
                {
                    max = number[i % 100] + max;
                }
            }
            endTime = clock();
            printf("非优化CPU时间:%d tick 结果%d\r\n", endTime - startTime,max);
        }
    }
    

    return 0;
}

上述代码运行

运行结果

 

  • 写回答

1条回答 默认 最新

  • benbenli 2021-05-25 13:10
    关注

    这里运行时间的主要因素是每次循环计算的区别。

    1)去分支:

                    unm = (number[i % 100] - 50) >> 31;
                    max = (number[i % 100] & unm) + max;

    2次取模:i % 100 假设结果为m

    2次数组小标寻址:number[m],假设结果问n

    以上两个2次,编译器能优化成各1次。

    1次减法 n - 50,假设结果为s

    1次移位 s >> 31,结果位unm

    1次按位与 n & unm,假设结果位 a

    1次加法 a + max

    共6次运算。其实取模的开销大于加减法大于按位与和移位。

     

    2)有分支:

                    if (number[i % 100] < 50) {
                        max = number[i % 100] + max;
                    }

    每次循环必须有的运算:

    1次取模:i % 100 假设结果为m

    1次数组小标寻址:number[m],假设结果问n

    1次小于比较 n < 50

    当 n < 50 时还有1次加法 n + max。(number[i % 100]编译器可以优化用if条件判断计算时的值)。

    所以每次循环只有3次或者3次运算。

    所以有分支的代码运算更快。去分支的代码,我认为不但性能差些,可读性也差些,不鼓励这样写代码。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 7月12日

悬赏问题

  • ¥50 求解vmware的网络模式问题
  • ¥24 EFS加密后,在同一台电脑解密出错,证书界面找不到对应指纹的证书,未备份证书,求在原电脑解密的方法,可行即采纳
  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥30 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?