【问题标题】:Overflow using Fixed-Point Chebyshev Method使用定点切比雪夫方法溢出
【发布时间】:2015-05-11 04:02:31
【问题描述】:

我在嵌入式系统中有一个算法,需要使用 Q15 定点算法计算 sin(theta)、sin(2*theta)、sin(3*theta) 等。 sin(theta) 和 cos(theta) 是使用 LUT/插值组合生成的,但我使用 Chebyshev 方法来计算高阶正弦,如下所示(伪代码):

 sinN1 = Comes from Q15 LUT/interp algorithm
 cosN1 = Comes from Q15 LUT/interp algorithm

 sinN2 = (cosN1*sinN1)>>14;
 sinN3 = (cosN1*sinN2)>>14 - sinN1;
 sinN4 = (cosN1*sinN3)>>14 - sinN2;
 ....

问题在于,在某些情况下,此方法产生的结果可能会溢出 Q15 变量。例如,让我们考虑当 theta =2.61697 时:

 sinN1 (Q15) = int(2**15*sin(2.61697)) = 16413
 cosN1 (Q15) = int(2**15*cos(2.61697)) = -28361
 sinN2 = (-28361*16413)>>14 = -28412            # OK
 sinN3 = (-28361*-28412)>>14 - 16413 = 32768    # OVERFLOW BY 1
 ..

我似乎从来没有溢出超过一两个 LSB。它似乎是复合量化的神器。我使用的是 ARM Cortex M4 处理器,所以我可以用相对较少的指令添加饱和逻辑,但是我正在做很多实时流 DSP,延迟要求非常低,所以我需要尽可能多地节省 CPU所以我想知道是否有更优雅的方式来处理这个问题。

【问题讨论】:

  • 您可能会使用无符号算术,因为 +/- 将通过检查象限来确定。可能有其他方法来估计函数和/或调整系数。您没有给出正在估计的实际功能吗?

标签: arm fixed-point trigonometry cortex-m


【解决方案1】:

我的数学家想建议保持对累积误差的估计,并以 sigma-delta 的方式对其进行校正,但我的务实程序员说这非常不切实际。

SSAT 指令将使您的结果饱和到您想要的任何位置,只需一个周期,并且应该可以通过任何非垃圾编译器上的 __ssat 内在函数轻松获得。由于任何非整数运算都不可避免地会累积错误,因此我不确定是否真的有比仅仅进行计算并花费一个额外的周期确保它在范围内更好的方法。


我不能完全解决的是,如果您可以通过涉足一些(内联)程序集来完全免费获得它,以获得内在函数没有公开的ssat 中的可选转换,在基于乘法/FP校正步骤是最大的误差源;类似(伪组装):

mul  tmp, cosN1, sinN2
ssat tmp, #16, tmp, asr #14
sub  sinN3, tmp, sinN1

只有当你能保证永远不会得到像 sinN3 = 0 - (-32768) 这样的东西时,你才能安全地逃脱。 QSUB16 很想取代 SUB,但是作为一个并行操作会用符号位的上半字做一些奇怪的事情,一旦你添加一个掩码或半字打包指令来纠正你已经丢失的“免费”游戏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 2011-06-18
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多