rust - 如何在 ARM 嵌入式 Rust 中使用更少的内存进行取模

标签 rust arm embedded modulo cortex-m

我在 STM32F446 MCU 上有一个 Rust 嵌入式项目。考虑下一行:

leds::set_g(self.next_update_time % 2000 == 0)

取模,网上看的,Cortex M4好像没有取模指令。相反,一个函数被添加到在软件中执行此操作的二进制文件中。使用cargo bloat(基于Google的Bloaty),可以找到。

File  .text    Size                 Crate Name
...
0.1%   6.9%    990B     compiler_builtins __udivmoddi4
...

令我惊讶的是,它只需要不到 1 KB 的内存。我想这已经很多了。其背后的代码也很长,参见this关联。我认为这个实现速度很快。幸运的是我还有空闲内存。

使用 opt-level = 'z' 不会改变这一点。

但是如果我买不起这个怎么办,我怎样才能让它占用更少的内存呢?

当然可以求助于 this 这样的解决方案可以,但随后我将失去使用 % 运算符的能力。

最佳答案

不确定 Rust 链接器有多聪明,但在许多嵌入式链接器实现中,您可以交换自己的 __udivmodi4 实现,该实现使用更小(但更慢)的方法,而不是编译器提供的版本。

一般来说,通用除法和取模在嵌入式平台上是昂贵的,但是除以常量通常可以通过智能编译器通过“固定”实现来专门化(通常有公约数的特殊情况 - 3, 5, 7, 10 , ETC)。

如果您可以控制应用程序,那么更改代码以除或模 2^N 显然是更好的选择(它折叠为除法的“右移”指令或“与”指令)模指令)。例如。在本例中,2048 可能接近 2000,可以接受,并将 1 KB 代码转换为 4 字节代码。

FWIW Rust 版本确实看起来有点胖 - GCC implementation例如要小得多。

关于rust - 如何在 ARM 嵌入式 Rust 中使用更少的内存进行取模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59054054/

相关文章:

c++ - 带参数的嵌入式系统上的最小 C++ 回调

rust - 类型不匹配错误 : expected `char` , 找到引用

c - ARM 汇编内联 C 互斥实现

assembly - 为 X86 编译时如何防止函数对齐到 16 字节边界?

linux - 是否可以在 Linux-x86-64 上为 Linux-ARM 构建 native gdb?

c - 用于嵌入式设备的 C 语言微型垃圾收集器

syntax - 从引用分配变量时,ref 和 & 有什么区别?

rust - 变量不需要是可变的,但它确实是可变的

Rust:带有匹配和变量绑定(bind)的奇怪语法