我在STM32F446 MCU上的Rust中有一个嵌入式项目。考虑下一行:
leds::set_g(self.next_update_time % 2000 == 0)
使用了模并在线阅读,看来Cortex M4没有模指令。取而代之的是,将一个函数添加到在软件中执行此操作的二进制文件。使用货膨胀(基于Google的Bloaty),可以找到它。
File .text Size Crate Name
...
0.1% 6.9% 990B compiler_builtins __udivmoddi4
...
令我惊讶的是,它仅占用不到一千字节的内存。我认为很多。其背后的代码也很长,请参见this链接。我认为此实现速度很快。幸运的是我有足够的记忆空间。
使用opt-level = 'z'
不会改变它。
但是,如果我负担不起,该如何占用更少的内存呢?
当然可以采用类似this的解决方案,但是后来我失去了使用%
运算符的能力。
[不确定Rust链接器的技巧如何,但是在许多嵌入式链接器实现中,您可以交换自己的__udivmodi4
实现,该实现优先使用较小(但较慢)方法而不是编译器提供的版本。
[一般而言,在嵌入式平台上,通用除法和取模很昂贵,但通常可以通过智能编译器的“固定”实现对常数进行除法(通常在特殊情况下使用常见除数-3、5、7、10,等等)。
如果可以控制应用程序,则最好将代码更改为以2^N
除或取模(将其折叠为除法的“右移”指令,或取模的“与”指令)。例如。在这种情况下,2048可能接近2000,可以将1 KB的代码转换为4字节的代码。
FWIW,Rust版本看起来确实有点发胖,例如GCC implementation小得多。