编译优化学习

转自:https://juejin.cn/post/6933180767656738824

1.介绍

代码 -> 词法语法分析 -> 语义分析 -> 中间代码生成 -> 目标代码生成
  • 编译器:中间代码生成。编译器会尝试对中间代码进行优化,通过减少无效或冗余的代码、计算强度优化等手段,以助于减少最终生成的指令数,或使用更高效的指令。编译器 为了提升代码最终的执行效率,会进行一个非常重要的步骤,就是编译优化
  • 指令集:基于中间代码生成机器可执行的目标代码,这个过程和操作系统、指令集、内存等相关。其中,不同的指令集也会带来不同的效率。

2.优化级别

在默认情况下,gcc 编译器不开启编译优化,因为编译器的目标是减少编译时间、保证编译结果能够按照期望进行测试。 (开启编译优化编译时长会增加,bin文件大小也会增加,但最终代码执行效率会增加) 

命令行执行开启编译优化:

g++ -O2 example.cpp -o example

cmake中开启编译优化:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") #变量拼接

#设置debug和release
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0")
# -DNDEBUG 常用的一个宏,用来禁用标准库中的所有断言(assert)调用,进一步提高代码的运行效率。
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O2 -DNDEBUG")
#需要在编译时置顶变量
cmake -DCMAKE_BUILD_TYPE=Debug/Release ..

不同编译优化级别编译时间、文件大小比较:

  • cmake -DCMAKE_BUILD_TYPE=Debug .. &&make -j12,编译优化级别O0,编译bin文件大小:723M,耗时8min 10s
  • cmake -DCMAKE_BUILD_TYPE=Release .. &&make -j12,编译优化级别O2 -DNDEBUG,编译bin文件大小:936M,耗时 11min 40s
  • cmake .. &&make -j12,编译优化级别O2,编译bin文件大小:946M,耗时 11min 58s

可见,编译优化等级越高,bin文件越大,编译耗时越长,执行效率会越高。

3.优化类型 

https://zhuanlan.zhihu.com/p/381490718,https://oi-wiki.org/lang/optimizations/

  • 常量传播
  • 常量折叠(替换)
  • 复写传播(替换)
  • 公共子表式消除
  • 无用代码消除。永远不能被执行到的代码或者没有任何意义的代码会被清除掉。
  • 方法内联。将比较简短的函数或者方法代码直接粘贴到其调用者中,以减少函数调用时的开销。
  • 循环旋转,循环不变量外提。
  • 循环展开。因为直接赋值的效率是最高的。for循环还有条件判断,循环条件变化这些。
  • 自动尾递归改写。

开编译优化也有副作用。

posted @ 2024-04-14 19:57  lypbendlf  阅读(6)  评论(0编辑  收藏  举报