news 2026/4/16 19:05:07

gcc的-O优化等级和编译后程序占用空间的关系

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gcc的-O优化等级和编译后程序占用空间的关系

文章目录

    • gcc的-O优化等级和编译后程序占用空间的关系
    • 概述
    • 笔记
    • -O0
    • -O1
    • -O2
    • -O3
    • -Os
    • -Ofast
    • -Og
    • -Oz
    • 不同优化等级下编译后的size比较
      • 不指定-O开关
      • -O
      • -O0
      • -O1
      • -O2
      • -O3
      • -Os
      • -Ofast
      • -Og
      • -Oz
      • 整理
    • 备注
    • END

gcc的-O优化等级和编译后程序占用空间的关系

概述

在调试固件,想看看可以选哪个优化等级,既不会增加代码体积,也不会妨碍单步调试。
不关心具体的优化标志,只关心大的-O优化等级开关。

编译优化标志(-fx)受到编译优化等级开关(-Ox)的控制. 如果一个编译优化标志在makefile中指定了,但是优化等级开关没达到(e.g. -O0), 这些指定的优化标志也不会生效。

如果不指定优化等级,默认的是-O0

然后比较一下同一个实际工程,用不同的优化等级,编译出的代码体积的差别。

gcc在线文档url https://gcc.gnu.org/onlinedocs/

笔记

-O0

-O0 Reduce compilationtimeandmakedebugging produce the expected results. This is the default. At , GCC completely disablesmostoptimization passes;they are not run evenifyou explicitlyenablethem on thecommandline, or are listed by as being enabled by default. Many optimizations performed by GCC depend on code analysis or canonicalization passes that are enabled by , and it would not be useful to run individual optimization passesinisolation. -O0-Q --help=optimizers-O

缩短编译时间,并确保调试能产生预期的结果。这是默认设置。
GCC 完全禁用了大多数优化过程;即便您在命令行中明确启用了这些过程,它们也不会被执行,而且在-O0中也不会被列为默认启用的状态。GCC 执行的许多优化过程都依赖于由-O0启用的代码分析或规范化过程,单独运行个别优化过程是毫无意义的。

-O1

-O -O1 Optimize. Optimizing compilation takes somewhatmoretime, and a lotmorememoryfora large function. With , the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time. -O -O is the recommended optimization levelforlarge machine-generated code as a sensible balance betweentimetaken to compile and memory use: higher optimization levels perform optimizations with greater algorithmic complexity than at.-O

-O -O1 是一样的。
优化编译会花费稍多的时间,对于大型函数来说,还会占用大量内存。
使用 -o 时,编译器会尝试减小代码大小和执行时间,但不会执行任何耗费大量编译时间的优化操作。
-O1 是推荐用于大型机器生成代码的优化级别,它在编译时间和内存使用之间达到了合理的平衡:更高的优化级别会执行算法复杂度更高的优化操作。

-O2

-O2 Optimize even more. GCC performs nearly all supported optimizations thatdonot involve a space-speed tradeoff. As compared to , this option increases both compilationtimeand the performance of the generated code. -O

-O2在-O1的基础上进一步优化。
GCC 会执行几乎所有不涉及空间与速度权衡的优化操作。与 -O1相比,此选项会增加编译时间,但提高生成代码的性能。

-O3

-O3 Optimize yet more. turns on all optimizations specified by and also turns on the following optimization flags: -O3-O2

-O3在-O2的基础上进一步优化。

-Os

-Os Optimizeforsize. enables all optimizations except those that often increase code size: -Os-O2 -falign-functions -falign-jumps -falign-labels -falign-loops -fprefetch-loop-arrays -freorder-blocks-algorithm=stc It also enables , causes the compiler to tuneforcode size rather than execution speed, and performs further optimizations designed to reduce code size. -finline-functions

-Os在-O2的基础上进一步优化。
优化以减小代码大小。启用除那些通常会增加代码大小的优化之外的所有优化
-对函数进行对齐
-对跳转进行对齐
-对标签进行对齐
-对循环进行对齐
-预取循环数组
-采用 stc 算法重新排列代码块, 它还使编译器能够针对代码大小而非执行速度进行优化,并执行进一步的优化以减少代码大小。
-内联函数优化

-Ofast

-Ofast Disregard strict standards compliance. enables all optimizations. It also enables optimizations that are not validforall standard-compliant programs. It turns on , and the Fortran-specific , unless is specified, and.It turns off.-Ofast-O3-ffast-math-fallow-store-data-races-fstack-arrays-fmax-stack-var-size-fno-protect-parens-fsemantic-interposition

-Ofast开启了所有的优化选项,这可能会引起问题。
忽略严格的标准。这能使所有优化生效。它还能使那些并非适用于所有符合标准的程序的优化生效。

-Og

-Og Optimize debugging experience. should be the optimization level of choiceforthe standard edit-compile-debug cycle, offering a reasonable level of optimizationwhilemaintaining fast compilation and a good debugging experience. It is a better choice thanforproducing debuggable code because some compiler passes that collect debug information are disabled at.-Og-O0-O0 Like , completely disables a number of optimization passes so that individual options controlling them have no effect. Otherwise enables all optimization flags exceptforthose that may interfere with debugging: -O0-Og-Og-O1

优化调试体验。应作为标准的编辑-编译-调试循环的优化级别首选项,既能提供合理的优化程度,又能保证快速编译和良好的调试体验。与生成可调试代码相比,这是一个更好的选择,会排除干扰调试操作的优化。

-Oz

-Oz Optimize aggressivelyforsize rather than speed. This may increase the number of instructions executedifthose instructions require fewer bytes to encode. behaves similarly to including enablingmostoptimizations. -Oz-Os-O2 If you use multiple options, with or without level numbers, the last such option is the one that is effective. -O Options of the form specify machine-independent flags. Most flags have both positive and negative forms;the negative form of is.In the table below, only one of the forms is listed—the one you typically use. You can figure out the other form by either removing ‘’ or adding it. -fflag-ffoo-fno-foono- The following options control specific optimizations. They are either activated by options or are related to ones that are. You can use the following flagsinthe rare cases when “fine-tuning” of optimizations to be performed is desired. -O

-Oz在-Os -O2的基础上进一步优化
优先考虑优化代码的大小而非速度。这样做可能会增加执行的指令数量,因为这些指令所需的编码字节数较少。其效果类似于启用大多数优化选项。

不同优化等级下编译后的size比较

就拿同一个开源工程中的一个提交为测试对象(e.g. bootloader工程的初始提交), 预留的编译后的目标size空间为16kb
因为程序空间用的差不多了,-O0编译后装不下,将.ld改一下,改为预留最大的MCU代码空间。

编译时,都是先clean, 再build
为了验证是否同一个配置,每次编译的rom-size, ram-size, build-time都一致,编译2次,进行参考。
应该同一个配置,每次编译出的rom-size, rame-size都是相同的,build-time可能稍有差别。

不指定-O开关

[1;4m SIZE LPC1769(bootloader)[0m FLASH24540bytes5% of 512kb150% of 16kb RAM3248bytes20% of 16kb14:04:53 Build Finished.0errors,14warnings.(took 10s.208ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH24540bytes5% of 512kb150% of 16kb RAM3248bytes20% of 16kb14:20:15 Build Finished.0errors,14warnings.(took 10s.63ms)

-O

[1;4m SIZE LPC1769(bootloader)[0m FLASH14120bytes3% of 512kb87% of 16kb RAM3248bytes20% of 16kb14:06:35 Build Finished.0errors,14warnings.(took 11s.232ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH14120bytes3% of 512kb87% of 16kb RAM3248bytes20% of 16kb14:29:29 Build Finished.0errors,14warnings.(took 11s.137ms)

-O0

[1;4m SIZE LPC1769(bootloader)[0m FLASH24540bytes5% of 512kb150% of 16kb RAM3248bytes20% of 16kb14:11:23 Build Finished.0errors,14warnings.(took 10s.175ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH24540bytes5% of 512kb150% of 16kb RAM3248bytes20% of 16kb14:30:25 Build Finished.0errors,14warnings.(took 10s.255ms)

-O1

[1;4m SIZE LPC1769(bootloader)[0m FLASH14120bytes3% of 512kb87% of 16kb RAM3248bytes20% of 16kb14:12:32 Build Finished.0errors,14warnings.(took 11s.180ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH14120bytes3% of 512kb87% of 16kb RAM3248bytes20% of 16kb14:31:22 Build Finished.0errors,14warnings.(took 11s.278ms)

-O2

[1;4m SIZE LPC1769(bootloader)[0m FLASH13348bytes3% of 512kb82% of 16kb RAM3248bytes20% of 16kb14:13:14 Build Finished.0errors,19warnings.(took 12s.143ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH13348bytes3% of 512kb82% of 16kb RAM3248bytes20% of 16kb14:32:15 Build Finished.0errors,19warnings.(took 11s.992ms)

-O3

[1;4m SIZE LPC1769(bootloader)[0m FLASH16428bytes4% of 512kb101% of 16kb RAM3248bytes20% of 16kb14:13:56 Build Finished.0errors,20warnings.(took 13s.309ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH16428bytes4% of 512kb101% of 16kb RAM3248bytes20% of 16kb14:33:08 Build Finished.0errors,20warnings.(took 13s.348ms)

-Os

[1;4m SIZE LPC1769(bootloader)[0m FLASH12308bytes3% of 512kb76% of 16kb RAM3248bytes20% of 16kb14:14:57 Build Finished.0errors,15warnings.(took 11s.581ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH12308bytes3% of 512kb76% of 16kb RAM3248bytes20% of 16kb14:33:51 Build Finished.0errors,15warnings.(took 11s.532ms)

-Ofast

[1;4m SIZE LPC1769(bootloader)[0m FLASH16428bytes4% of 512kb101% of 16kb RAM3248bytes20% of 16kb14:15:47 Build Finished.0errors,20warnings.(took 13s.511ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH16428bytes4% of 512kb101% of 16kb RAM3248bytes20% of 16kb14:34:44 Build Finished.0errors,20warnings.(took 13s.412ms)

-Og

[1;4m SIZE LPC1769(bootloader)[0m FLASH14188bytes3% of 512kb87% of 16kb RAM3248bytes20% of 16kb14:16:43 Build Finished.0errors,16warnings.(took 10s.719ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH14188bytes3% of 512kb87% of 16kb RAM3248bytes20% of 16kb14:35:43 Build Finished.0errors,16warnings.(took 10s.875ms)

-Oz

[1;4m SIZE LPC1769(bootloader)[0m FLASH12308bytes3% of 512kb76% of 16kb RAM3248bytes20% of 16kb14:18:05 Build Finished.0errors,15warnings.(took 11s.632ms)
[1;4m SIZE LPC1769(bootloader)[0m FLASH12308bytes3% of 512kb76% of 16kb RAM3248bytes20% of 16kb14:36:40 Build Finished.0errors,15warnings.(took 11s.735ms)

通过多次编译一个配置的工程,可知,编译出来的东西是确定的,编译时间稍有差别。

整理

优化等级程序输出占用的size(byte)RAM输出占用的size(byte)编译时间
不指定-O开关24540324810s.208ms
-O024540324810s.175ms
-Ofast16428324813s.511ms
-O316428324813s.309ms
-Og14188324810s.719ms
-O14120324811s.232ms
-O114120324811s.180ms
-O213348324812s.143ms
-Os12308324811s.581ms
-Oz12308324811s.632ms

从以上统计数据,可知:
RAM总是没有优化,如果想减少RAM的用量,那么程序中数据结构用的变量要减少才行。RAM的优化和代码编译开关没关系。
对于不同的编译开关,编译时间是有不同,但是我们中的大多数人都是不关心的。
我们其实最关心的是编译出的程序size和程序的稳定性(不会因为编译优化使程序的逻辑出错)
对于编译出的程序的size和编译开关的选择,可知:
不加优化开关时,等同于 -O0
按照编译开关和编译出的程序占用空间的关系,可以看出有些编译开关编译效果是差不多的,按照程序占用空间从大到小,如下:
不指定-O开关/ -O0, 代码占用空间最大
-Ofast/-O3 次之
-Og 次之
-O/-O1 次之
-O2 次之
-Os/-Oz 代码占用空间最小

备注

并不是优化等级越高,编译后程序的占用空间越小。根据以上实验结果,可以看出O3优化比O2优化占用的程序空间还多。

如果是调试程序,启用-Og, 调试感觉是最好的(是有优化的,代码占用空间在O2和O3之间,但是一点不影响单步调试),在每一句代码处都能单步,每一个变量都能观察到。

如果在-Og下,编译出的程序占用空间装不下了,那可能说明需求/实现 = 不合理/可以优化/应该重新评估。
如果需求不能改, 实现逻辑也没有太多可优化的地方,就只能用-Os/-Oz来优化,但是单步调试受影响(单步时,可能下一步就跳过了很多代码行).

END

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 14:51:19

早期缺陷的预测性检测:从理论到实践的全景解析

在持续集成的软件开发环境中,缺陷预测已成为质量保障体系的核心环节。本文基于机器学习技术与代码质量度量,深入探讨了如何在编码阶段识别潜在缺陷模式,通过建立预测模型将缺陷发现时机从测试阶段大幅提前至开发阶段,显著降低项目…

作者头像 李华
网站建设 2026/4/16 13:39:04

AutoGPT部署包免费提供,配套GPU算力限时优惠

AutoGPT部署包免费提供,配套GPU算力限时优惠 在企业自动化需求日益增长的今天,一个能“自己动手”的AI助手已经不再是科幻场景。想象一下:你只需说一句“帮我写一份关于AI投资趋势的报告”,几小时后,一份结构完整、数据…

作者头像 李华
网站建设 2026/4/16 13:39:05

AutoGPT镜像SLA保障说明:服务可用性达99.9%

AutoGPT镜像SLA保障说明:服务可用性达99.9% 在企业级AI应用逐步从“能用”迈向“好用”的今天,一个核心问题日益凸显:如何让像AutoGPT这样的自主智能体,在真实生产环境中稳定、持续地运行?传统聊天机器人或许可以容忍短…

作者头像 李华
网站建设 2026/4/16 13:39:06

Dify部署Qwen3-8B智能体全过程记录(附常见错误解决)

Dify 集成 Qwen3-8B 构建本地智能体的实践之路 在当前大模型技术快速迭代的背景下,越来越多开发者开始探索如何在有限资源下构建真正可用的 AI 智能体。我们不再满足于“调用云端 API”的黑箱模式——数据隐私、响应延迟和成本不可控等问题促使人们将目光转向本地化…

作者头像 李华
网站建设 2026/4/15 23:37:56

语音交互+多模态支持,LobeChat如何引领下一代聊天界面革新?

语音交互多模态支持,LobeChat如何引领下一代聊天界面革新? 在AI助手逐渐从“能对话”走向“懂场景”的今天,用户对聊天界面的期待早已超越了简单的文本问答。我们不再满足于复制粘贴问题、逐字敲击输入——而是希望像与真人交谈一样&#xff…

作者头像 李华
网站建设 2026/4/16 13:39:04

19、时间序列数据可视化与前端工具选择

时间序列数据可视化与前端工具选择 1. 数据可视化前的准备与前端工具概述 在完成数据收集和存储后,就可以着手进行数据的可视化工作,也就是绘制图表。和数据轮询与存储引擎一样,前端工具也需要具备灵活性。理想的前端工具应能绘制任意 RRD(Round Robin Database)中的任意…

作者头像 李华