gcc - ARM GCC 编译器“buggy”转换
问题描述
问题
我正在对 STM32F051 进行闪存优化。据透露,float
和int
类型之间的转换会消耗大量的闪存。
深入研究后发现,转换为int
大约需要 200 字节的闪存;而转换为unsigned int
大约需要1500个字节!
众所周知,两者的int
区别unsigned int
仅在于对“符号”位的解释,因此这种行为对我来说是一个很大的谜。
注意:执行 2 阶段转换float
-> int
->unsigned int
也仅消耗大约 200 个字节。
问题
分析一下,我有这样的问题:
1) 的转换机制是float
什么unsigned int
。为什么在同一时间转换float
-> int
->unsigned int
占用这么少内存时占用这么多内存空间?也许它与 IEEE 754 标准有关?
float
2) 当使用转换-> int
->unsigned int
而不是直接float
->时,是否会出现任何问题int
?
3) 是否有任何方法可以包装float
->unsigned int
转换以保持低内存占用?
注意:这里已经提出了熟悉的问题(试图了解编译器如何完成转换/转换,例如,从 float 转换为 int 时),但仍然没有明确的答案,我的问题是关于内存使用情况。
技术数据
- 编译器:ARM-NONE-EABI-GCC (gcc version 4.9.3 20141119 (release))
- 单片机:STM32F051
- MCU内核:32位ARM CORTEX-M0
代码示例
float
->int
(约 200 字节的闪存)int main() { volatile float f; volatile int i; i = f; return 0; }
float
->unsigned int
(~1500 字节!闪存)int main() { volatile float f; volatile unsigned int ui; ui = f; return 0; }
float
->int
->unsigned int
(大约 200 字节的闪存)int main() { volatile float f; volatile int i; volatile unsigned int ui; i = f; ui = i; return 0; }
解决方案
float
从to的转换unsigned int
应该大于从float
to的转换没有根本原因signed int
,实际上可以使float
tounsigned int
转换小于float
tosigned int
转换。
我使用 GNU Arm Embedded Toolchain(版本 7-2018-q2)进行了一些调查,据我所知,大小问题是由于 gcc 运行时库中的缺陷造成的。出于某种原因,该库没有为 Arm V6m 提供 __aeabi_f2uiz 函数的专用版本,而是依赖于更大的通用版本。
推荐阅读
- php - 从实体字段的列定义中获取 ENUM 值
- postgresql - 错误:多次指定表名“va_user_feedback”
- excel - Selection.InsertFile FileName:="C:\Users\FileName.Docx" 行代码适用于 Word VBA 但不适用于 Excel VBA
- javascript - 如何在nodejs中处理来自android的JSON
- spring-boot - ManyToOne:deleteAll() & delete(object) 不起作用
- clickhouse - 从事件中提取会话
- xpath - jmeter xpath通过文本和父元素定位元素
- neo4j - Neo4J - CQL - 如何完全匹配这种模式?
- boost - 如何构建 boost::asio::experimental
- php - D3.js 未捕获的类型错误: