编译器优化之Loop Unrolling

前言

开发过程中,我们有可能会写段循环语句来执行一段代码,完成一个功能点。运行没问题看到结果后,一切万事大吉,功能完成了就可以了。但对于这段代码背后是如何执行的,很少有人愿意去深究,除非涉及到一些性能问题,不得不改进循环时才会去真正的探究本质。其实对于我们写的循环语句,编译器有可能帮助我们做了一定程度上的优化。这种优化的技术,就叫做Loop Unrolling 。

Loop Unrolling (循环展开)

循环展开,是一种牺牲程序的大小来加快程序执行速度的优化方法。可以由程序员完成,也可由编译器自动优化完成。循环展开最常用来降低循环开销,为具有多个功能单元的处理器提供指令级并行。也有利于指令流水线的调度。

本文主要探讨编译器对于Loop Unrolling优化问题。

有如下代码:

c++ int loop(int i) {     for(;i<10;i++);     return i; }

对于聪明的人类来说,看一下逻辑就可以得到结果,如果参数i小于等于10,则返回10;否则返回i(即一次比较就知道结果)。

但对于编译器来说,在编译代码时会有自己的一套规则。当编辑优化参数设置为-o0时,编译器会按部就班的来执行代码逻辑。

即会按照流程执行for语句,然后再返回结果。如下是汇编结果,

不优化.png

可以看到将值与9比较然后决定是返回循环还是结束循环。

那有没有聪明一点的做法呢?答案是肯定的,在编译器优化选项中设置-o2,编译器会对函数做优化,执行Loop Unrolling,函数会被优化成一条简单的if指令,如下是汇编结果,

优化.png

可以看到,直接跟10比较来返回结果。

编译器将一个循环转变为不需要循环的过程,这个过程就叫做Loop Unrolling。

有关汇编指令的问题可以去简单的复习一下汇编。

总结

Loop Unrolling 有助于提升App的性能,但也有相应的缺点。它的优缺点如下:

  • 优点

    • 分支预测失败减少。

    • 如果循环結構内语句没有数据相关,增加了并发执行的机会。

    • 可以在执行时动态循环展开。这种情况在编译时也不可能掌握。

  • 缺点

    • 代码膨胀

    • 代码可读性降低,除非是编译器透明执行循环展开。

    • 循环結構内包含递归可能会降低循环展开的效益。

### Keil 编译器优化设置指南 Keil 是一款广泛应用于嵌入式系统的集成开发环境 (IDE),其编译器提供了多种优化选项,可以显著提升程序性能或减少代码体积。以下是关于如何配置这些选项的具体说明: #### 1. **优化目标的选择** 在 Keil 中,可以通过调整编译器优化级别来平衡代码大小和执行速度的需求。通常有以下几个级别的优化可供选择: - `None`:不启用任何优化。 - `Size`:优先考虑减小代码尺寸[^1]。 - `Speed`:优先考虑提高运行效率。 这些选项可以在项目属性中的 C/C++ 设置页面找到。通过右键点击工程名称 -> `Options for Target...` -> `C/C++` 页面,在 “Optimization” 下拉菜单中进行选择。 #### 2. **特定功能优化** 针对某些特殊需求,还可以进一步细化优化策略: #### 减少代码体积 - 启用函数内联 (`Inline Functions`) 可以消除函数调用开销并缩短最终二进制文件长度,但可能增加内存占用。 ```c static inline void myFunction() { // Function body here. } ``` - 利用链接器脚本剔除未使用的全局变量与静态数据段,从而节省存储空间。 #### 提升性能表现 - 开启循环展开 (`Loop Unrolling`) 技术能够加速重复操作密集型算法处理时间成本较高的场景下尤为有效。 - 调整寄存器分配策略使得频繁访问的数据尽可能驻留在硬件寄存器而非RAM之中,进而降低延迟并增强吞吐量。 #### 3. **调试模式 vs 发布模式** 当切换到发布版本构建时,默认情况下会关闭大部分诊断信息输出以及断点支持等功能以便于实现更紧凑高效的可执行映像。因此建议仅保留必要的错误检测机制而移除非生产环境中才会用到的服务组件比如printf系列打印语句等不必要的消耗资源的操作。 ```python # 示例 Python 伪代码展示逻辑流程控制结构转换为汇编指令后的差异对比分析方法论之一部分片段示意如下所示: def example_function(x, y): result = x * y + (x / y) if y !=0 else None return round(result ,2 )if isinstance( result,( int,float ))else 'Invalid Input' ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值