你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】浮点 DSP 运算效率不高

[复制链接]
STMCU小助手 发布时间:2022-2-26 15:49
问题:, F# t4 \7 g( U8 q" o$ f
该问题由某客户提出,发生在 STM32F407IGT6 器件上。据其工程师讲述:由于在其产品中,需要使用STM32 进行大量的浮点数以及浮点 DSP 运算,所以针对 STM32 的浮点数运算能力及 DSP 运算能力做了相关的测试,但测试结果不理想。STM32F407 在 144MHz 主频下,对于表(一)程序的运算耗时为:9105uS。没有体现出硬件浮点运算应有的运算能力。
3 h0 ?) ~8 ~2 \2 j9 X. K5 w
0 u; `9 j) [# ^/ G O[XBED$]RI]EA`QC3}{}`UP.png
5 Y# k. w, }0 T) L
( K' r4 ]2 V6 f9 r4 y! r& t调研:& ]1 W* i: j, X
使用 Keil MDK4.21 创建工程对表(一)的程序进行测试。在工程设置中,选择支持浮点运算指令。将编译器的优化等级设置为 LEVEL1,然后编译运行。通过示波器测量主程序在调用该函数之前和在该函数返回之后在 I/O 管脚上所发出的脉冲之间的时间差,来判断 STM32 运行该函数所花费的时间。* u4 d, D. i" M/ k: V- I% V+ O

: X& }( i: T8 a( _1 c  {# |' u1. 当 STM32 的主频为 168MHz,使用 SRAM2 存贮变量的条件下,测得时间消耗为:7840uS。修改工程设置,将内存的使用由 SRAM2 转成 CCM,重新编译、下载、运行,测得时间消耗为:7840uS。- x0 v8 N% R% C3 Y: ?1 j- o
2. 修改工程设置,将优化等级由 LEVEL1 换成 LEVEL3。为了避免编译器把整个测试函数优化掉,修改该函数如表(二)。重新编译、下载、运行,测得时间消耗为:7660uS。
3 F. i( i& W3 G; U3. 修改程序代码,将序函数 sin()和 cos()分别替换成 ARM DSP library 中的 arm_sin_f32()和arm_cos_f32(),如表(三)所示。重新编译、下载、运行,测得时间消耗为:748uS。3 o2 C5 ]; i5 D2 T
4. 修改代码,将计算中所用到的小数常量,表示成单精度,如表(四)所示。重新编译、下载、运行,测得时间消耗为:130uS。
& B  G3 k0 a$ }3 x; \   
$ j  _3 m* ~2 K/ I3 _; { {EP_WQI$WLFMRVKW5Z6G~ES.png
0 P( [* O! c  M5 ?
0 G/ ^1 a9 w( U+ q0 ]) h [5BV~NS3U)LZ82334K@J9L7.png
0 G3 b1 ^# o. G% W5 i, N) u# q6 e  V& i3 c2 A
( h& {0 {! s+ Z% W; M7 P4 L
结论:
9 H  U+ r* f: B2 I3 V三个方面的原因导致了计算效率降低:
9 x9 \. ^5 i  T) G0 z3 V1. 编译器的优化等级不够,以至生成的代码本身的效率低下;2 N9 j& s( X' V6 k
2. 表达式上的漏洞,造成部分计使用了双精度浮点运算;5 g) g7 W8 s1 f& H5 V! y5 P
3. 三角函数库的选取不当,导致在计算正弦、余弦过程中引入了大量的双精度浮点运算;& ], x5 w* _5 J
   ! }8 U2 Y  Z) |8 M$ ?# P! T7 S
处理:
- ~/ X8 [8 r2 r( `! [0 i1. 合理选用编译器的优化等级,提高代码的执行效率;4 C7 e) z$ E6 N, E, H# a+ W
2. 在计算表达式中,强制常量为单精度浮点数,以避免引入双精度浮点数动算;
0 o: t9 L0 B1 ]. Y3. 选用 ARM 公司提供的,采用单精度浮点数优化的三角函数库,以避免由普通的数学函数库引入的双精度浮点数运算;. D0 w; T9 Y0 k1 v' W4 y
" ]3 W* g9 }5 i# E" ?" ~  v( s
建议:
& s7 {, v6 ^( e# G从应用角度看,Cortex-M4 可以认为是 Cortex-M3 的加强版。相对 Cortex-M3,Cortex-M4 主要从两个方面进行了改进:
+ A0 [2 f' y( y" i* ]1. 增加了 DSP、SIMD 指令;
% i7 z& i' s. s) r2. 增加了单精度浮点运算单元;
; ]4 f, F8 P! E' B" }* Q, ~- j+ q第 1 点使得 Cortex-M4 拥有高速的定点 DSP 处理能力,第 2 点则使得 Cortex-M4 拥有强大的数学运算能力。受益于 Cortex-M4 的优异的处理性能,以及高效的总线与存贮器接口,STM32F4 系列 MCU在数据处理方面有着非凡的表现。不过,要使硬件上的性能得以充分的发挥,除了对算法本身进行优化以外,对一些相关因素也要仔细斟酌:0 n( b" M0 U, R5 |: W
1. 恰当的设置 Flash 缓冲区的参数。在 STM32F4 中,为了匹配 Flash 存贮器与 CPU 之间的对数据、指令的吞吐速率,设有指令缓冲区和数据缓冲区。复位后缓冲区是不工作的,需要软件予以开启,并设置恰当的等待周期数。没有缓冲区的参与,运行在 Flash 中的程序,在运效率上会大幅度的降低。
5 f' @' A% r/ S, z1 e2. 选择高效的存贮器来存放数据。快速的数据存取是保证 CPU 不间断的执行指令的前提。这一点上,不仅要考查存贮器本身的速率,还要看是否有其它的处理单元与 CPU 分享该存贮器。比如,在STM32F4 中,将数据放在 CCM 存贮器中,要比放在 SRAM1 中更能保证 CPU 对数据的存取速率,因为CCM 存贮器是 CPU 独享的,而 SRAM1 还可能被 DMA 访问。- e3 \) H7 v, F5 [5 `; y
3. 根据 CPU 指令集的特点,合理的选取计算的数据类型。比如,要计算 16 位的 DSP 运算,最好把变量和常量定义成 16 位数据,这样有利于编译器使用 SIMD 指令对代码进行优化。在单精度浮点数能够满足要求的情况下,将变量或常量定义成单精度类型,有利于编译器使用单精度浮点运算指令,对代码优化。
  ?3 ~2 I% o$ S: B0 s9 e% Q4. 选择针对 Cortex-M4 进行优化的数学函数库。ARM 公司为 Cortex_M4 的提供了一整套的 DSP、浮点数运算库,其效率远高于编译器自带的函数库。$ v2 ]3 i7 ]9 T8 C: ?
5. 编译器的优化等级是一个重要的设置选项,不同的优化等级下,所生成的代码的效率是有很大差别的。
- _4 g2 ]+ k2 j* t6 U9 Z5 [1 b6. 对于高频次使用的数据,要考虑放在寄存器类型的变量中。通常,CPU 存取操作数的最快捷的方式是寄存器寻址,可以做到零时钟花费。* U. R5 R& j1 |+ K. x. [: Z0 ~
7. 合理安排计算次序,考虑是否可以以乘法代替除法。在数学中,乘法和除法是一对逆运算,除以一个数与乘于这个数的倒数可以等同起来。然而在 CPU 的指令实现中,乘法和除法的计算速度上是有很大差别的,通常乘法的计算速度远高于除法的计算速度。所以,有必要在运算中,使用乘法来代替除法。比如: 可以使用 来代替。2 ]9 z/ c( A' b  }% O0 p$ s
8. 找出算法中的重复计算,将其合并,只计算一次。对这样的计算,完全可以在第一次计算之后将结果放在中间变量中,而在后面的计算中直接引用。& L- w" E1 K* R  p0 y$ B* t2 S0 |
9. 对于复杂的计算,考虑是否能用查表来代替。查表是一种快速得出结果的好方法,它以牺牲存贮器空间来换取速度。在存贮器空间不是很紧张的情况下,用查表代替计算还是很划算的。( k8 a" x, ]4 j1 D# O

8 V4 z' q1 w: E1 t
_P~216{ZTLVY$S[ISQWN~AA.png
RRN_8LIMI}I9%8JJ$G~X)TS.png
赞 收藏 1 评论0 发布时间:2022-2-26 15:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版