Inline 参数对IAR编译的影响

简介: 来自博客 http://blog.chinaunix.net/uid-25445243-id-3477017.html 我们的程序,一般由各种函数组成。

来自博客

http://blog.chinaunix.net/uid-25445243-id-3477017.html

我们的程序,一般由各种函数组成。有的函数,只在程序内被调用一次。有的,在多个地方被调用过。

        对于 只在程序内被调用一次 的函数。======如果选择大小优化,编译器不会把它当作函数来处理,而是Inline掉。(c语言里,可以保留函数的样子,便于阅读)但是,程序的执行,直接被嵌进去了,没有CALL,RETURN等动作。

        那么,有的函数,只在程序内被调用两次 如何处理呢?只在程序内被调用五次呢?

        下面,是两个小程序 选择不同的 选项 及Inline threshold 参数   编译后大小对比:

size(speed)后面的数字,是 Inline参数,再后面,就是bin文件大小。

size    1    6.37 KB (6,528 字节)
speed  16   15.7 KB (16,108 字节)

另一个小程序:

size    1   5.85 KB (5,996 字节)
speed  16   7.14 KB (7,312 字节)

        Inline节省的是call, return的开销,所以肯定能提高速度,但如果函数体稍大的话,肯定会增加代码大小,而且调用次数越多代码就增加越快。所以IAR编译器要求你提供一个threshold数字以便进行抉择。应该没有不良影响。

        内联函数就是小型函数,牺牲空间来节省函数调用的开销,一般用作比较小的函数,即函数内部没有循环、开关语句等。内联函数被发明出来就是为了取代C中的宏,因为宏是单纯的替换而没有类型检查所以经常出毛病,比如:

        #define MAX(a, b) (a) > (b) ? (a) : (b)

        如果你在代码中这样写:

        int a = 5, b = 10;

        int max = MAX(++a, b);     // a自增了两次

        int max = MAX(++a, b+10);     // a自增了一次

        a的自增次数竟然由与其比较的数字的大小来决定!?这肯定不是你想要的结果。

        所以最好的办法是这样:


        template
        inline T max(const T& t1, const T& t2)
        {
                return t1 > t2 ? t1 : t2;
        }

        这样的话如果你这样写:

        int max = max(a, b);
        其实就被替换为了:
        int max = a > b ? a : b;


        虽然看起来和宏差不多,但是比宏多了类型检查,而且内联函数使用的是真正的函数的特性,而不是宏的function-like,模拟函数的功用。

        内联函数是为频繁使用、并且过程不大的小型函数设计的,我说了它是以牺牲代码空间来节省函数调用的开销,内联函数使用不当就会造成代码膨胀,所以使用它一定要小心。

 

        #pragma inline = forced

        你如果正常使用inline,只是建议编译器此函数需要inline,但编译器是否真的inline,它会自己做出判断,比如和你设置的优化等级有关(见上图,要设置high的优化等

级),用了forced则编译器会强制inline

        register修饰变量也只是一种建议。

 

        如何定义inline函数?     

        inline函数传统上只有C++支持,但IAR EW也支持在C代码中使用inline.
        #pragma inline:建议编译器对紧随其后的函数进行inline处理
        #pragma inline = forced: 强制编译器对紧随其后的函数进行inline处理
相关文章
|
4月前
|
存储 API 内存技术
GD32通过SPI和QSPI模式读取GD的NOR Flash
GD32通过SPI和QSPI模式读取GD的NOR Flash
592 2
|
5月前
|
机器学习/深度学习 传感器 算法
基于多模态感知与深度学习的智能决策体系
本系统采用“端-边-云”协同架构,涵盖感知层、计算层和决策层。感知层包括视觉感知单元(800万像素摄像头、UWB定位)和环境传感单元(毫米波雷达、TOF传感器)。边缘侧使用NVIDIA Jetson AGX Orin模组处理多路视频流,云端基于微服务架构实现智能调度与预测。核心算法涵盖人员行为分析、环境质量评估及路径优化,采用DeepSORT改进版、HRNet-W48等技术,实现高精度识别与优化。关键技术突破包括跨摄像头协同跟踪、小样本迁移学习及实时推理优化。实测数据显示,在18万㎡商业体中,垃圾溢流检出率达98.7%,日均处理数据量达4.2TB,显著提升效能并降低运营成本。
233 7
|
5月前
|
传感器 自动驾驶 安全
GPTP时钟授时服务器应用介绍、GPTP时钟、GPTP授时服务器、Gptp时钟
GPTP时钟基于IEEE 802.1AS标准,用于时间敏感网络中的高精度时间同步。系统包含主时钟(如SYN2413型PTP主时钟)和从时钟,通过绝对与相对时间同步实现全网一致性。其工作原理涉及硬件时间戳采样、P2P路径延时测量等技术,确保ns级精度。广泛应用于汽车(自动驾驶、V2X通信)、工业自动化(生产流水线、过程控制)、通信(5G网络、光通信)及智能交通(车路协同、轨道交通)等领域,保障实时性与安全性。文章版权归西安同步所有,严禁侵权。
|
12月前
|
人工智能 自然语言处理 测试技术
通义灵码一周年
【10月更文挑战第5天】通义灵码一周年体验
210 5
|
12月前
|
存储 C++ 容器
(3)Qt中的变体数据类型(QVariant)
QVariant是Qt中一个强大的变体数据类型,能够存储和管理多种Qt和C++基本数据类型,包括自定义类型,并通过setValue()和value()方法进行赋值和取值。
677 9
(3)Qt中的变体数据类型(QVariant)
阿里云蝉联亚太市场份额第一
Gartner®发布《MarketShare: Services, Worldwide, 2023》,2023年阿里云在亚太地区laaS市场份额继续排名第一,相比2022年提升0.8个百分点,达22.2%。
|
传感器 数据采集 运维
ERP系统中的生产线监控与异常处理解析
【7月更文挑战第25天】 ERP系统中的生产线监控与异常处理解析
554 8
|
监控 前端开发 JavaScript
JS Navigator.sendBeacon 可靠的、异步地向服务器发送数据
Navigator.sendBeacon 是一个用于发送少量数据到服务器的 API,尤其适用于在页面即将卸载时发送数据,如日志记录、用户行为分析等。 与传统的 AJAX 请求不同,sendBeacon 方法的设计目标是确保数据在页面卸载(例如用户关闭标签页或导航到新页面)时能够可靠地发送。 Navigator.sendBeacon 方法可用于通过 HTTP POST 将少量数据异步传输到 Web 服务器。 它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:XMLHttpRequest)发送分析数据的一些问题。
406 1
|
Ubuntu Docker 容器
迁移harbor
在Ubuntu 22.04 LTS环境中,已安装Docker的Harbor从v2.5.3迁移到v2.9.0,保留原有镜像数据。参考官方文档[v2.9.0](https://goharbor.io/docs/2.9.0/),执行包括数据目录复制、解压新版本、配置harbor.yml和docker-compose.yml、运行安装脚本等步骤。迁移后,通过测试推拉镜像确保功能正常。注意查看潜在的部署问题。
301 0
|
数据可视化 Java API
【Spring Boot 快速入门】五、Spring Boot集成Swagger UI
【Spring Boot 快速入门】五、Spring Boot集成Swagger UI
1497 0
【Spring Boot 快速入门】五、Spring Boot集成Swagger UI