阶乘算法优化

__attribute__((noinline))
int test(int n)
{int fact = 1, num = n + 1;int i =1;for (i = 1; i < num; i++) {fact *= i;}return fact;
}
int main()
{printf("%d\n", test(1000000000));
}

为方便分析,函数calc()前面加上__attribute__((noinline)),禁止GCC把calc内联在main()中。此外,calc()中,fact类型是int,main()中调用calc(1000000000),会导致fact溢出,但不影响测试,不用管它。

编译一下,然后用time命令测量下运行耗时:

[root@localhost ~]# gcc jiecheng.c -o jiecheng
[root@localhost ~]# time ./jiecheng
0real    0m25.159s
user    0m25.160s
sys     0m0.000s

用时25s

#include <stdio.h>
int test(int n)
{int fact0 = 1,fact1 = 1,fact2 = 1,fact3 = 1;int i =1;for (i = 1; i < n; i+=4) {fact0 *= i;fact1 *= i+1;fact2 *= i+2;fact3 *= i+3;}return fact0 * fact1 *fact2 * fact3;
}
int main()
{printf("%d\n", test(1000000000));
}

注意:这里为方便讲解,假设n总是4的倍数。如果要处理n不是4的倍数的情况,只需要在主循环体外,增加一个小的循环单独处理最后的n%4个数,也就是最多3个数即可,对整体性能影响几乎为0.

编译一下,然后用time命令测量下运行耗时:

[root@localhost ~]# time ./jiecheng2
0real    0m9.067s
user    0m9.066s
sys     0m0.004s

运行耗时从原来的25秒降到了9秒,性能提升了!你以为这就完了?

这还不是最终的结果,因为我们还有一个优化技巧还没加上,最终优化后的结果是0.3秒!文末会讲!先不着急,咱们一个一个来讲!

关于循环展开:你真的理解吗?

看到这里,有人会说,不就是循环展开嘛,很简单的,没什么好研究的,而且加了优化选项之后,编译器会自动进行循环展开的,没必要手动去展开,也就没有研究的价值了!

真的是这样吗?先尝试回答下面几个问题:

  1. 循环展开为什么能提高程序性能,其背后的深层次原理是什么?

  2.  循环随便怎么展开都一定可以提高性能吗?

  3. 用了优化选项,编译器一定会帮我们自动进行循环展开优化吗?

第一个问题后面会详细讲解,我们先用实例回答下第2个和第3个问题。

先看第2个问题。

循环随便展开都能提高性能吗?

我们把jiecheng_2.c稍微改一下,命名为jiecheng_3.c:

#include <stdio.h>
int test(int n)
{int fact=0;int i =1;for (i = 1; i < n; i+=4) {fact *= i;fact *= i+1;fact *= i+2;fact *= i+3;}return fact;
}
int main()
{printf("%d\n", test(1000000000));
}

仍然是循环展开,只不过把循环展开的方式稍微改了一下。再编译一下,用time命令测量下运行耗时:

[root@localhost ~]# time ./jiecheng3
0real    0m17.095s
user    0m17.090s
sys     0m0.004s

和jiecheng.c相比运行耗时只减少了8秒!为什么同样是循环展开,jiecheng_2.c只需要1.6秒,而jiehceng_3.c却要17秒,为什么性能差异这么大呢?别着急,后面细讲。

再看第三个问题,加了优化选项,编译器一定会帮我们自动进行循环展开优化吗?一试便知

O3,编译器一定会循环展开吗?

重新编译下test.c, test_2.c, 和test_3.c,只不过,这次我们加上-O3优化选项,然后分别用time命令再测量下运行时间。

先是test.c:

[root@localhost ~]# gcc jiecheng.c -o jiecheng -O3
[root@localhost ~]# time ./jiecheng
0real    0m3.457s
user    0m3.453s
sys     0m0.004s

加了-O3优化后,程序耗时从原来的25秒降到了3秒,性能提升确实非常明显!是否好奇,-O3选项对test.c做了什么样的优化,能够把程序耗时降到八分之一?这个后面再讲。

现在,我们先试下test_2.c:

[root@localhost ~]# gcc jiecheng_2.c -o jiecheng2 -O3
[root@localhost ~]# time ./jiecheng2
0real    0m1.011s
user    0m1.008s
sys     0m0.004s

同样,加了-O3后,程序耗时从原来的9秒降到了1秒!此外,在同样加了-O3的情况下,使用了循环展开的test_2.c,程序耗时仍然是test.c的八分之一可见,编译器确实优化了一些东西,但是,无论是否加-O3优化选项,进行手动循环展开的test.c仍然是性能最好的!

最后,再试下test_3.c:

[root@localhost ~]# gcc jiecheng_3.c -o jiecheng3 -O3
[root@localhost ~]# time ./jiecheng3
0real    0m0.004s
user    0m0.000s
sys     0m0.004s

看到了吧?同样加了-O3优化选项的前提下,性能仍然与test_2.c相差甚远!(我这里测试的结果与文章的不一样),也是与CPU有关,这里使用的是龙芯Loongson-3A R3 (Loongson-3B3000) @ 1450MHz

小结一下我们现在得到的几组测试结果:

        jiecheng.c                jiecheng_2.c        jiecheng_3.c

-O0        25.159秒            9.075秒                  17.054秒      

-O3        3.463秒               1.008秒                 0.0003秒

原谅链接

改几行代码,for循环耗时从3.2秒降到0.3秒!真正看懂的都是牛人!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/145645.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大话Presto 】- 核心概念

文章目录 前言Operator Model And Iterator Model系统组成Connector数据模型查询执行模型StatementStageTaskSplitDriverOperatorExchangePipeLine 总结 前言 Presto&#xff08;PrestoDB&#xff09;是一个FaceBook开源的分布式MPP SQL引擎&#xff0c;旨在处理大规模数据的查…

全新的FL studio21.2版支持原生中文FL studio2024官方破解版

FL studio2024官方破解版是一款非常专业的音频编辑制作软件。目前它的版本来到了全新的FL studio21.2版&#xff0c;支持原生中文&#xff0c;全面升级的EQ、母带压线器等功能&#xff0c;让你操作起来更加方便&#xff0c;该版本经过破解处理&#xff0c;用户可永久免费使用&a…

spark 窗口滑动用于在不同的数据块之间执行操作

在 Scala 中进行分布式执行&#xff0c;例如使用 Apache Spark&#xff0c;可以通过设置窗口滑动来实现不同 RDD 之间的关联处理。窗口滑动是一种窗口操作&#xff0c;用于在不同的数据块之间执行操作。 以下是一个简单的示例&#xff0c;演示如何在 Spark 中使用窗口滑动&…

「校园 Pie」 系列活动正式启航,首站走进南方科技大学!

PieCloudDB 社区校园行系列活动「校园 Pie」已正式启动。「校园 Pie」旨在促进数据库领域的学术交流&#xff0c;提供一个平台让学生们了解最新的数据库发展趋势和相关技术应用。 在「校园 Pie」系列活动中&#xff0c;PieCloudDB 社区将携拓数派技术专家&#xff0c;社区大咖…

可以免费使用的设计素材网站分享

UI设计师最怕什么&#xff1f; 没有创意&#xff0c;没有灵感&#xff0c;没有思路&#xff01; 在哪里可以得到idea&#xff1f;别担心&#xff0c;往下看&#xff01; 你知道网络有多大&#xff0c;你想要什么吗&#xff1f;今天&#xff0c;我想和大家分享一些宝藏网页设…

用户运营:如何搭建用户分析体系

在运营的工作范畴中&#xff0c;用户运营是很重要的一个环节&#xff0c;甚至有公司会设置专门的“用户运营”岗位。 用户运营的价值体现在多个方面&#xff0c;不仅可以帮助引流、吸引更多用户使用产品&#xff0c;在用户正式使用产品之后的运营则更为重要。通过日常用户运营&…

Angular 组件介绍及使用(一)

Angular 概述 Angular 是一个用于构建 Web 应用程序的开源前端框架&#xff0c;由 Google 团队开发和维护。它采用 TypeScript 编程语言&#xff0c;并借鉴了一些传统的 Web 开发模式和最佳实践&#xff0c;提供了强大而灵活的工具和特性。 以下是 Angular 的一些概述要点&am…

让Git自动忽略指定文件

要让Git忽略指定文件&#xff0c;你可以使用.gitignore文件来实现。.gitignore文件允许你指定要从版本控制中排除的文件和文件夹。 以下是如何创建和设置.gitignore文件以忽略指定文件的步骤&#xff1a; 1.在你的项目根目录下创建一个名为.gitignore的文件。 2.使用文本编辑…

SpringMVC调用流程

SpringMVC的调用流程 SpringMVC涉及组件理解&#xff1a; DispatcherServlet : SpringMVC提供&#xff0c;我们需要使用web.xml配置使其生效&#xff0c;它是整个流程处理的核心&#xff0c;所有请求都经过它的处理和分发&#xff01;[ CEO ] HandlerMapping : SpringMVC提供&…

转录组分析小故事丨什么是RNAseq?

揭开转录组分析的面纱 亲爱的读者: 欢迎来到生物信息奇妙之旅&#xff01;我是您的导航员&#xff0c;今天将带您走进玉米的微观世界&#xff0c;一探真核生物有参转录组分析的秘密。 想象一下&#xff0c;我们将穿梭于DNA与RNA的世界&#xff0c;用数据的眼睛揭示生命的奥秘&a…

第四代智能井盖传感器:万宾科技助力城市安全

在繁华喧嚣的城市里人来人往&#xff0c;井盖作为基础设施的一个组成部分在路面上分布范围广。然而这些看似普通的井盖却存在着位移、水浸的风险&#xff0c;可能给我们的生活带来诸多不便&#xff0c;更会威胁到我们的人身安全。如何有效监测和管理井盖的状态&#xff0c;成为…

为什么选择CodeEase?

目录 为什么选择CodeEase核心功能后端前端 框架结构总结 为什么选择CodeEase CodeEase是一个标准化的低代码平台 愿景 我们励志开发一站式服务&#xff0c;缩短网站开发周期&#xff0c;降低程序bug率&#xff0c;减少开发人力和成本&#xff0c;推出了多租户SaaS平台开发模板…

SpringCloud Alibaba组件入门全方面汇总(上):注册中心-nacos、负载均衡-ribbon、远程调用-feign

文章目录 NacosRibbonFeignFeign拓展 Nacos 概念&#xff1a;Nacos是阿里巴巴推出的一款新开源项目&#xff0c;它是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos致力于帮助用户发现、配置和管理微服务&#xff0c;它提供了一组简单易用的特性集&am…

电源地虚接,导致信号线发烫

音频板的信号是经过隔直电容接到音频板的。

利用(Transfer Learning)迁移学习在IMDB数据上训练一个文本分类模型

1. 背景 有些场景下&#xff0c;开始的时候数据量很小&#xff0c;如果我们用一个几千条数据训练一个全新的深度机器学习的文本分类模型&#xff0c;效果不会很好。这个时候你有两种选择&#xff0c;1.用传统的机器学习训练&#xff0c;2.利用迁移学习在一个预训练的模型上训练…

JAVA JPA 使用实体类注解 @CreatedDate @LastModifiedDate自动生成创建和修改时间

JPA 使用实体类注解 CreatedDate LastModifiedDate自动生成创建和修改时间 说明&#xff1a;jpa实体添加数据库自动生成创建和修改时间 1.ApplicationBootstrap增加以下注解 EnableJpaAuditing2.实体类增加注解以下注解 Table(name"user") JsonIgnoreProperties(v…

【Linux专题】firewalld 过滤出接口流量

【赠送】IT技术视频教程&#xff0c;白拿不谢&#xff01;思科、华为、红帽、数据库、云计算等等_厦门微思网络的博客-CSDN博客文章浏览阅读428次。风和日丽&#xff0c;小微给你送福利~如果你是小微的老粉&#xff0c;这里有一份粉丝福利待领取...如果你是新粉关注到了小微&am…

智慧工地解决方案,实现安全预警、机械智能监控、作业指导、绿色施工、劳务管理、工程进度监控、施工质量检查

智慧工地云平台全套源码 智慧工地平台采用先进的云计算、物联网和大数据技术&#xff0c;可以实现智慧工地方案的落地。能够实现实时掌控工地活动及各项进度&#xff0c;有效预防违章施工。能够为工地提供多项服务&#xff0c;如安全预警、机械智能监控、作业指导、绿色施工、劳…

JVM bash:jmap:未找到命令 解决

如果我们在使用JVM的jmap命令时遇到了"bash: jmap: 未找到命令"的错误&#xff0c;这可能是因为jmap命令没有在系统的可执行路径中。 要解决这个问题&#xff0c;可以尝试以下几种方法&#xff1a; 1. 检查Java安装&#xff1a;确保您已正确安装了Java Development …

Spring Boot EasyPOI 使用指定模板导出Excel

相信大家都遇到过&#xff0c;用户提出要把界面上的数据导成一个Excel&#xff0c;还得是用户指定的Excel格式&#xff0c;用原生的POI&#xff0c;需要自己去实现&#xff0c;相信是比较麻烦的&#xff0c;所以我们可以使用开源的EasyPOI. 先上个图&#xff0c;看看是不是大家…