Arm STMCUBEIDE-H7系列强制使用SMLAL(带累积的有符号乘法(32×;32+;64),64位结果)指令
STM32CUBEIDE编译器生成效率低下的代码Arm STMCUBEIDE-H7系列强制使用SMLAL(带累积的有符号乘法(32×;32+;64),64位结果)指令,arm,stm32,Arm,Stm32,STM32CUBEIDE编译器生成效率低下的代码 int16_t OscPhase[NumOsc]; int32_t OscInc[NumOsc]; int32_t OscVol[NumOsc]; int32_t Sine[65536]; int64_t OscTotal; and then in main() : OscTotal = 0; for (i = 0; i < NumOsc; i++)
int16_t OscPhase[NumOsc];
int32_t OscInc[NumOsc];
int32_t OscVol[NumOsc];
int32_t Sine[65536];
int64_t OscTotal;
and then in main() :
OscTotal = 0;
for (i = 0; i < NumOsc; i++)
{
OscPhase[i] = OscPhase[i] + OscInc[i];
OscTotal = OscTotal + Sine[OscPhase[i]] * OscVol[i];
}
int16\t OscPhase[NumOsc];
国际石油公司(NumOsc);
int32_t OscVol[NumOsc];
int32_t Sine[65536];
国际贸易总额;
然后在main()中:
OSCTOAL=0;
对于(i=0;i
我希望H7使用SMLAL指令进行最终的乘法和累加,但它执行MUL.W,它只给出一个32位的结果,然后使用ADD.W和ADC.W将这32位添加到最终的64位结果中
关于如何强制它使用正确的代码,有什么建议吗?对代码进行了一些实验后
#include <stdint.h>
int64_t mac (int64_t sum, int32_t x, int32_t y) {
return sum + ((int64_t)x*y);
}
当使用ARM GCC 7.2.1和标志-march=armv7e-m-mcpu=cortex-m7-O3
编译时,如果-O1
或未指定优化级别,则不会生成SMLAL
指令
没有强制转换,它不会生成SMLAL
,因为它正在执行32 x 32=>32乘法,而SMLAL
会生成32 x 32=>64
如果在循环中使用,
mac
函数似乎是内联的,因此没有额外的分支。尝试osctall=osctall+(int64_t)Sine[OscPhase[i]*(int64_t)OscVol[i]代码>或osctall=osctall+((int64_t)正弦[OscPhase[i]]*OscVol[i])代码>我有一个遥远的记忆,必须将所有操作数强制转换为64位类型,才能让keil编译器吐出SMLAL
您正在使用的编译器是什么?它是STM的新STM32CubeIDE,似乎使用了过时的GCC。你是对的-我最终得到了相同的答案,即将所有字符转换为64位是使用SMLAL的唯一方法。谢谢。我发现使用-O3时,编译器展开了M7上不需要的代码-正如您所说,O1会转储无法正确累积的代码。我发现-O2是最可靠的方法。我将尝试使用您的MAC声明,看看它是否内联,因为这样可以避免每次更改行时都需要检查汇编代码:-)编辑:是的,它内联了它。下一个问题是它执行64位加载,然后存储其每一侧,而不是将OSCTOAL保留在寄存器对中直到结束。正在做那件事。谢谢你的帮助
mac:
smlal r0, r1, r3, r2
bx lr