编译原理之美
宫文学
北京原点代码 CEO
46197 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
编译原理 · 期中考试周 (1讲)
编译原理之美
15
15
1.0x
00:00/00:00
登录|注册

27 | 代码优化:为什么你的代码比他的更高效?

用LLVM来演示优化功能
如何做本地优化
一些优化的场景
了解代码优化的目标、对象、范围和策略
代码优化

该思维导图由 AI 生成,仅供参考

在使用 LLVM 的过程中,你应该觉察到了,优化之后和优化之前的代码相差很大。代码优化之后,数量变少了,性能也更高了。而针对这个看起来很神秘的代码优化,我想问你一些问题:
代码优化的目标是什么?除了性能上的优化,还有什么优化?
代码优化可以在多大的范围内执行?是在一个函数内,还是可以针对整个应用程序?
常见的代码优化场景有哪些?
这些问题是代码优化的基本问题,很重要,我会用两节课的时间带你了解和掌握。
当然了,代码优化是编译器后端的两大工作之一(另一个是代码生成),弄懂它,你就掌握了一大块后端技术。而学习代码优化的原理,然后通过 LLVM 实践一下,这样原理与实践相结合,会帮你早日弄懂代码优化。
接下来,我带你概要地了解一下代码优化的目标、对象、范围和策略等内容。

了解代码优化的目标、对象、范围和策略

代码优化的目标
代码优化的目标,是优化程序对计算机资源的使用。我们平常最关心的就是 CPU 资源,最大效率地利用 CPU 资源可以提高程序的性能。代码优化有时候还会有其他目标,比如代码大小、内存占用大小、磁盘访问次数、网络通讯次数等等。
代码优化的对象
从代码优化的对象看,大多数的代码优化都是在 IR 上做的,而不是在前一阶段的 AST 和后一阶段汇编代码上进行的,为什么呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了代码优化的基本概念和实现方法,以及在LLVM中演示优化功能的过程。代码优化是提高程序对计算机资源利用效率的过程,包括性能、代码大小、内存占用、磁盘访问次数和网络通讯次数等方面的优化。在LLVM中,通过opt命令和Pass来进行代码优化,可以指定不同的优化算法和级别。文章还强调了可用表达式分析和活跃性分析在本地优化中的重要性,以及LLVM采用的SSA格式对优化算法的便利性。总的来说,本文深入浅出地介绍了代码优化的原理和实践,对读者了解代码优化具有指导意义。文章内容丰富,涵盖了代码优化的基本概念、LLVM中的优化演示以及实现优化的方法和工具,适合对代码优化感兴趣的读者阅读学习。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理之美》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(11)

  • 最新
  • 精选
  • 渔子长
    讲得太好了,市面上的书上确实看不到这些东西。

    作者回复: 谢谢肯定! 我们计划下一步就出成书:) 另外,限于专栏的篇幅,很多知识点还都没讲到、讲透,甚至后端部分还可以进一步通俗化。这个遗憾准备在出书的时候补上。

    2019-11-07
    2
    16
  • westfall
    既然有工具可以帮我们做优化,开发的时候是不是就不用考虑性能的问题了

    作者回复: 这是个好问题。语言的设计者经常会被问到这个问题。 这个问题的标准答案是:在大部分情况下,用比较正常的方式写程序即可。 这句话是什么意思呢?因为优化算法是能够识别那些常用的编程模式,从而做优化。比如,你正常的写一个循环操作,编译器就可能给你做循环展开、循环向量化等优化。如果你写得太特别,它可能就难以识别了,也就没办法帮你优化了。 但是,如果你的程序对性能特别敏感,那就需要了解编译器做优化的原理,主动向它靠拢。比如说,对于Java和JavaScript,两个重要的优化是内联优化和逃逸分析,但你的程序要符合一定的条件才会被内联。你写程序的时候,最好保证对象别逃逸,这样会大大降低内存管理的负担,并且会导致其他优化的可能。有个开源软件,Skia,是二维渲染引擎,Chrome、Android和Flutter都是用它。在其官网上,对于在windows上编译,它“强烈建议”用clang来编译,而不是用微软的工具链,因为Skia是针对clang的优化算法(在llvm中实现)做调优了的,所以性能相差很大。 另外,我在第二季《编译原理实战课》里讲优化更多,并且结合实际编译器来介绍。如果你希望对优化有更多了解,可以去那里看看。

    2020-05-22
    7
  • honnkyou
    “所以,你可以遍历一个 Value 的所有 User,把它替换成另一个 Value,这就是拷贝传播”老师这句话不是很理解。

    作者回复: 在做拷贝传播的优化时,要知道一个变量在哪里被使用。比如下面的例子中,y在第二个语句被使用。这样就可以在第二句中,把y替换成x。 y := x z := 2 * y Value和User的结构,保存了Value和User之间的引用关系,从而有利于去执行各种优化算法。

    2019-11-26
    5
  • Eric
    老师,我想我问一下公共子表达式消除和拷贝传播是从前往后进行还是反向进行?看这个例子好像哪个方向都可以..

    作者回复: 从前向后。前面用某个表达式定义的变量,后面可能被重新定义掉。这时,可用表达式的集合就要修改。

    2019-11-05
    2
  • 潜龙勿用
    宫老师,请问栈上分配属于什么优化?过程间优化吗?

    作者回复: 优化技术可以按多种角度分类,本地优化、全局优化和过程间优化只是一种分类角度。 栈上分配按这个分类方法不好归类。本地优化也可以产生栈上分配的效果,比如在C++或Java里声明一个本地对象,退出这个方法就不再用了,那么就可以栈上分配。

    2021-07-14
    2
  • coconut
    其中要注意的一点,是要把第一行命令生成的 fun1.ll 文件中的“optone”这个属性去掉,因为这个它的意思是不要代码优化。 optone 单词应该是 optnone吧?

    作者回复: 你很细心,确实应该是optnone! 多谢指出!

    2021-01-06
  • LDxy
    代码优化之后大变样,单步调试的时候是不是很困难?

    作者回复: 编译器会尽量友好地支持调试,llvm也提供了这方面的帮助。 但是,你说的对。优化有的代码,跟源代码的对应肯定是有问题的。开启优化后调试,有时会遇到一些状况,比如断点加不上,等等。

    2019-10-27
    2
  • Geek_e00a1a
    之前看过LLVM 的介绍书籍:《Getting Started with LLVM Core Libraries》,一直对 IR 中提到的Pass优化没有理解,还是老师讲的透彻 ~~~ 感谢老师的付出!!!
    2022-12-06归属地:北京
    2
  • 一张钞票
    a := b c := b + b c := b d := b + b e := d 这个反向扫描,第一遍扫e := d和第二遍的扫d := b + b能再详细讲讲嘛,这块没看懂,为什么要把d加入到集合?,后面为什么又要删?
    2020-09-16
    5
    1
  • Join
    看到这里,再次感受到原理的重要性,LLVM和Go Compiler的实现好像,特别是优化这边
    2021-11-17
收起评论
显示
设置
留言
11
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部