在使用ARM / Keil编译器为小型ARM处理器编译C ++时,我正在努力解决性能问题。
在执行某些处理的函数中,我有以下结构的代码:
{
MyClass temp = global_variable_input;
Operation 1 on temp;
Operation 2 on temp;
...
Operation N on temp;
global_variable_output = temp;
}
MyClass用于建模数学对象,唯一的成员是32位整数(即,对象的完整大小为4个字节)。
所有操作都涉及使用重载运算符或MyClass方法,并将“temp”的值更改为结果。有些操作很简单,内联(在类中内联声明的方法),有些操作更复杂,需要生成对方法的调用。
看一下编译器为我的例程生成的汇编程序代码,我注意到编译器为堆栈中的“temp”分配空间,并且每个操作(也是内联的!)都将操作的结果存储在放在堆栈中,然后继续使用上次操作中存储在寄存器中的值。对于非内联类型,编译器将指针传递给寄存器r1中的对象(this)和指向堆栈中创建的另一个对象的指针,以将结果存储在寄存器r0中。
代码实现了一个信号处理算法,您可以将其想象为temp上的一系列算术运算,因此在每次单个操作(可能只是一个操作码)之后,使用这个额外的“store”指令和相应的内存访问在实施过程中引入了巨大的性能损失。
理想情况下,我希望编译器仅使用寄存器来完成操作,而不是保持每次操作后需要更新的“temp”的堆叠版本。
另一个愿望是它将对象的当前值简单地使用寄存器传递给方法(就像ARM C调用约定为普通C函数指定的那样)并以相同的方式获得结果,而不是使用指针到记忆位置。
我要求的太多了吗?如何让我的ARM / Keil编译器以这种方式工作?
PS:这个函数很简单,所以它不像编译器需要在堆栈中分配我的变量,因为它用完了寄存器。我怀疑它之所以这样做是因为它需要有一个指针传递给非内联方法,然后认为有必要保持堆栈中的值始终是最新的。
非常感谢!
答案 0 :(得分:1)
使用像
这样的参考MyClass& temp = global_variable_input;
会避免在堆栈(本地存储)上分配MyClass
的完整副本
虽然有
Operation 1 on temp;
Operation 2 on temp;
// ...
也会影响原始global_variable_input
。
答案 1 :(得分:-2)
您可以将您的班级更改为结构。它将存储在堆栈而不是堆中。