优化 c 中函数的参数(GCCarm)

optimize function's parameter in c (GCCarm)

我的微控制器内存有限。(使用 arm gcc) 我应该尽可能高效地编写我的代码。考虑函数自爆:

int foo(uint32_t a , float b)
{
    .....
    return 0;
}

所以我有两个参数 ab。现在,如果我将参数更改为 *a 并且 *b 是函数在执行期间比第一个函数占用更少的内存:

int foo(uint32_t *a,float *b)
{
    ....
    return 0;
}

如果参数变成字符串或数组(int、float ....)怎么办? 任何参考都会很棒。谢谢

应用程序二进制接口 (ABI) 中定义的 ARM 过程调用标准指出,传递给函数的前四个字大小的参数将在寄存器 R0-R3 中传输。

由于指针的大小也是 32 位的,因此这两个签名之间没有太大区别。

int foo(uint32_t a, float b)
int foo(uint32_t *a, float *b)

两者都将在 r0 中具有 a,在 r1 中具有 b 并且在 r0 中再次具有 return 值。

ARM 是一种 RISC 架构,它有许多寄存器和一些琐碎的功能,您甚至可以完全避免接触任何内存。

如果您正在使用微控制器,最好检查一下您是否真的应该使用浮点数。因为它们可能不受您所针对的核心的原生支持。

我会查看 ARM Cortex-A Series Programmer's Guide(其中大部分也适用于微控制器),尤其是第 15 章和第 17 章,以了解有关 ARM 应用程序开发技巧的更多信息。

使用指针实际上会浪费内存。这有两个原因。

1.寄存器优化丢失

调用foo的代码必须将变量的地址作为参数传递。如果传递的变量是本地变量,它可能在寄存器中,但因为你获取了它的地址,所以它 必须 放在堆栈上。一般来说,在寄存器中使用变量比在堆栈中使用变量更快。

2。调用后变量值未知

当你给出变量函数的地址时,编译器不再知道变量是否被修改,如果再次读取它必须刷新它。

 uint32_t u = 1;
 float f = 2.0f;
 foo(&u, &f); // 1. Address taken, u and f cannot be register variables
 // 2. What is value of u now? It must refreshed from memory before addition happens
 u++;

底线:除非万不得已,否则不要获取基本类型的地址。

字符串和数组已经使用地址传递,因此没有其他选择。