优化 c 中函数的参数(GCCarm)
optimize function's parameter in c (GCCarm)
我的微控制器内存有限。(使用 arm gcc)
我应该尽可能高效地编写我的代码。考虑函数自爆:
int foo(uint32_t a , float b)
{
.....
return 0;
}
所以我有两个参数 a
和 b
。现在,如果我将参数更改为 *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++;
底线:除非万不得已,否则不要获取基本类型的地址。
字符串和数组已经使用地址传递,因此没有其他选择。
我的微控制器内存有限。(使用 arm gcc) 我应该尽可能高效地编写我的代码。考虑函数自爆:
int foo(uint32_t a , float b)
{
.....
return 0;
}
所以我有两个参数 a
和 b
。现在,如果我将参数更改为 *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++;
底线:除非万不得已,否则不要获取基本类型的地址。
字符串和数组已经使用地址传递,因此没有其他选择。