【问题标题】:When is it more efficient to use CORDIC or a polynomial approximation?什么时候使用 CORDIC 或多项式近似更有效?
【发布时间】:2013-03-14 18:35:39
【问题描述】:

我正在研究一种不具备浮点硬件,而只有 16 位 ALU 和 40 位 MAC 的架构。

我已经在此架构上的软件中实现了 32 位单精度浮点加法/减法、乘法、余弦、正弦、除法、平方根和范围缩减。

为了实现余弦和正弦,我首先使用论文"ARGUMENT REDUCTION FOR HUGE ARGUMENTS" by K.C. NG 中描述的方法使用范围缩减 然后我实现了一个余弦和正弦函数,它们是余弦和正弦函数在 -pi/4 到 +pi/4 范围内的多项式逼近。我参考了 Hart 等人的《计算机近似》一书。多项式。

我也听说我应该考虑 CORDIC 算法。但是,我想知道是否有人知道它是否比我已经使用的方法更有效(在吞吐量、内存开销和所需的指令数量方面)?我在多核架构上实现了我的软件功能,其中每个内核只有 128 个字的指令存储器和一个 128 个字的 16 位数据存储器。 我还尝试搜索如何为余弦和正弦实现 CORDIC 算法,但我找不到任何用于 32 位浮点实现的好的资源。有人有建议吗?

谢谢!

【问题讨论】:

  • 您现有的实现是否存在性能问题?
  • 性能很慢。此外,我还将比较我的软件实现与是否有硬件浮点乘法器或加法器或两者都可用。我一直在想的一个问题是,CORDIC 怎么样,它是如何在这里发挥作用的?我应该将其视为一种选择吗?为什么?我还没有找到任何好的资源来回答这个关于 32 位浮点的问题。
  • 您是否使用霍纳来评估多项式?您使用了哪些次数多项式?
  • 我的正弦方程是 ax+bx^3+cx^5+dx^7 的形式。我的余弦方程是 a+bx^2+cx^4+dx^6 的形式。我不确定你所说的使用霍纳是什么意思?我通过使用计算机近似书找到了系数 a、b、c 和 d。我使用了一个多项式来保证我的精度达到 24 位。
  • 对于Horner's method,计算 a+x*(b+x*(c+x*d)) 的 cos 和类似的 sin。请注意,wikipedia 表示“当硬件乘法器可用时(例如,在 DSP 微处理器中),查表方法和幂级数通常比 CORDIC 更快”。

标签: c algorithm math assembly floating-point


【解决方案1】:

CORDIC 为您每次循环迭代提供一位,因此在软件中实现它可能会比您的多项式版本慢。这也可能是为什么很难找到关于CORDIC软件实现的文章的原因:它的性能较差,所以没人打扰。

回复您的评论:Horner's method 是通过重复添加系数,然后乘以变量 x,从最高阶系数到最低阶系数评估多项式的​​做法。相比之下,朴素的方法(即,首先评估x 的幂,然后将它们乘以它们的系数并将它们相加)需要更多的工作并且在数值上可能不如霍纳的方法稳定。

你还没有确切地提到你是如何评估你的多项式的,所以我会建议一个公式:

x2 = x * x
cos = ((COS_D * x2 + COS_C) * x2 + COS_B) * x2 + COS_A
sin = (((SIN_D * x2 + SIN_C) * x2 + SIN_B) * x2 + SIN_A) * x

请注意,如果将常数调整到评估函数的范围,而不是使用泰勒系数,则可以获得更高的精度。 (再次道歉,如果您做了部分或全部这些事情,但您没有提及您已经尝试过的事情......)


这可能与您的情况不太相关(大概只有一个 16x16 位 MAC),但如果您的处理器可以一次启动多个算术评估,如果您将评估写在树状形式,避免了一些操作的顺序依赖:

x2 = x * x
x4 = x2 * x2
cos = (COS_D * x2 + COS_C) * x4 + (COS_B * x2 + COS_A)
sin = ((SIN_D * x2 + SIN_C) * x4 + (SIN_B * x2 + SIN_A)) * x

如果您的处理器具有向量 ALU,则此公式也表明它的生产用途...

【讨论】:

  • FWIW,您的第二个评估方案称为 Estrin 方法。
  • 顺便说一句,我强烈推荐维基百科关于 Estrin 方法的文章中引用的书:Elementary Functions: Algorithms And Implementation,作者 Jean-Michel Muller
  • @comingstorm,Horner 的方法可能会为我提供更高的吞吐量和更容易理解的数据路径。
  • @comingstorm,对于正弦,我使用了多项式 ax+bx^3+cs^5+dx^7。我将输入乘以 4/pi(需要 1 个核心),因为我的范围缩减算法减小了 -pi/4 和 +pi/4 之间的范围,但我的多项式在 [0,1] 之间运行。我在另一个核心中使用了这个值来创建 x^3、x^5 和 x^7。前两个核心将它们的结果发送到另一个核心以创建 ax、bx^3、cx^5 和 dx^7。这些结果被发送到一系列加法器核心(1个加法需要两个核心)来创建ax+bx^3,然后是ax+bx^3+cx^5,然后是ax+bx^3+cx^5+dx^7 .这需要 8 个内核(忽略 *4/pi)。 Horner 的方法需要 10 个内核。
  • 基本上是面积与吞吐量。我担心核心用完,所以我尽可能减少了面积。
【解决方案2】:

如果 MAC 明显快于等价的移位和与加法序列,请使用多项式;甚至不考虑CORDIC(除了可能减少一个或两个范围的步骤)。很难准确地找到 FP CORDIC 算法,因为该标准始终适用于任何使用 FP 的系统(过去约 35 年),因此不考虑 CORDIC。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多