首页 > 解决方案 > ARM GCC 编译器“buggy”转换

问题描述

问题

我正在对 STM32F051 进行闪存优化。据透露,floatint类型之间的转换会消耗大量的闪存。

深入研究后发现,转换为int大约需要 200 字节的闪存;而转换为unsigned int大约需要1500个字节!

众所周知,两者的int区别unsigned int仅在于对“符号”位的解释,因此这种行为对我来说是一个很大的谜。

注意:执行 2 阶段转换float -> int->unsigned int也仅消耗大约 200 个字节。

问题

分析一下,我有这样的问题:

1) 的转换机制是float什么unsigned int。为什么在同一时间转换float-> int->unsigned int占用这么少内存时占用这么多内存空间?也许它与 IEEE 754 标准有关?

float2) 当使用转换-> int->unsigned int而不是直接float->时,是否会出现任何问题int

3) 是否有任何方法可以包装float->unsigned int转换以保持低内存占用?

注意:这里已经提出了熟悉的问题(试图了解编译器如何完成转换/转换,例如,从 float 转换为 int 时),但仍然没有明确的答案,我的问题是关于内存使用情况。


技术数据

代码示例

  1. float-> int(约 200 字节的闪存)

    int main() {
    volatile float f;
    volatile int i;
    i = f;
    return 0;
    }
    
  2. float-> unsigned int(~1500 字节!闪存)

    int main() {
    volatile float f;
    volatile unsigned int ui;
    ui = f;
    return 0;
    }
    
  3. float-> int-> unsigned int(大约 200 字节的闪存)

    int main() {
    volatile float f;
    volatile int i;
    volatile unsigned int ui;
    i = f;    
    ui = i;
    return 0;
    }
    

标签: gccmemorycompiler-constructionunsignedstm32f0

解决方案


float从to的转换unsigned int应该大于从floatto的转换没有根本原因signed int,实际上可以使floattounsigned int转换小于floattosigned int转换。

我使用 GNU Arm Embedded Toolchain(版本 7-2018-q2)进行了一些调查,据我所知,大小问题是由于 gcc 运行时库中的缺陷造成的。出于某种原因,该库没有为 Arm V6m 提供 __aeabi_f2uiz 函数的专用版本,而是依赖于更大的通用版本。


推荐阅读