转自: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循环还有条件判断,循环条件变化这些。
- 自动尾递归改写。
开编译优化也有副作用。
标签:文件大小,CMAKE,CXX,学习,编译,FLAGS,优化 From: https://www.cnblogs.com/BlueBlueSea/p/18134596