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

时间:2015-02-04 08:38:16

标签: c arm function-pointers

我的microController中的内存有限。(使用arm gcc) 我应尽可能高效地编写代码。考虑功能爆炸:

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

所以我有两个参数ab。现在,如果我将参数更改为*a*b,则该函数在执行期间比第一个函数需要更少的ram:

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

如果参数变成String或数组(int,float ....)怎么办? 任何引用都会很棒。感谢

2 个答案:

答案 0 :(得分:2)

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

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

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

a中的r0b中的r1r0中的值都会再次返回。

ARM是一种RISC架构,它有许多寄存器,并且具有琐碎的功能,你甚至可以远离触摸任何内存。

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

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

答案 1 :(得分:2)

使用指针时,实际上可以浪费内存。这有两个原因。

<强> 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++;

底线:除非必须,否则不要使用原始类型的地址。

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