【问题标题】:Computational cost of trig functions [duplicate]三角函数的计算成本
【发布时间】:2012-08-31 01:57:09
【问题描述】:

可能重复:
How do Trigonometric functions work?

Sin、Cos、Tan 和 Atan 等三角函数的计算实际上涉及什么?

我想我在我的代码中找到了一个优化,我可以避免使用这些函数中的任何一个,并将问题基于斜率而不是角度。这意味着用几个除法运算来代替上述三角函数。但我想更多地了解这些三角函数的内容,以便我可以比较我的新代码(从基本数学运算数量的角度来看)。或者我刚刚找到了一种更迂回的方法来做同样的事情,或者更糟糕的是,引入了一种效率较低的方法。

使用 C++ 和 Python,但我认为这些与语言无关,因为数学运算成本与最原始的运算相关。

【问题讨论】:

  • 如果您担心,您可以预先计算所需的值(在应用程序启动时,或将它们保存在文本文件中并加载),将它们存储在表格中,然后查看他们起来。
  • 我不是在这个特定的情况下,这更多是为了理解我一直不清楚的东西。
  • @AK:在这种情况下,您可能想看看这个问题:stackoverflow.com/questions/345085/…

标签: math optimization trigonometry


【解决方案1】:

您需要分析您的代码!

您需要自己对此进行概要分析。根据我的结果,三角函数大约需要 100 ns,除法大约需要 20 ns。这可以很容易地转换为答案。但同样,最重要的是您在硬件上对此进行分析。这样,您就可以为您的系统获得完全正确的答案和知识。

【讨论】:

  • 当然可以完成工作,但它并不能真正告诉我为什么它更快。
【解决方案2】:

现代 x86 处理器的指令集中包含三角函数,但它们需要很多周期才能执行。所以 if 你在这样一个处理器上,如果你的代码中没有依赖项(即你不需要一个 sin 计算的结果来启动下一个),那么你可能不会比直接使用 sin 和 cos 快多少,因为它们将完全流水线化,实现每个周期 1 的有效速率。

【讨论】:

  • 我相信完整的三角函数比每个周期 1 个慢得多。在等待 trig 函数完成时,您也许可以做其他事情,但 trig 操作本身并不是以这种方式流水线化的。
  • 因此,您可以通过使用近似值来加快速度,或者您可能不会——这取决于您的应用程序以及您可以采用多少近似值。
  • 此外,重新计算数学以避免触发有时可以大大加快和简化代码,完全独立于触发操作本身的成本。
  • C sin() 通常不会编译为 x87 fsin,大多数编译器。这些指令是经过大量微编码的,例如 Skylake (agner.org/optimize) 上的 53 到 105 uop,并且吞吐量可能与延迟一样糟糕(非流水线)。在 Nehalem(您发布此答案时为当前),fsin 为 100 微秒,延迟 = 吞吐量 = 40 到 100 个周期。许多数学库已经没有使用它了。
【解决方案3】:

(这原本是对codekaizen回答的评论,但是写的有点长……)

(Codekaizen):现在大多数三角函数都是作为查找表实现的。

嗯.. 由于大多数三角函数采用双精度参数,因此查找该值是不切实际的。我相信大多数人都会查找两边的整数,然后从那里进行插值(即 Sin(5.279) 是从 Sin(5) 到 Sin(6) 的 27.9%)。直接计算价值的工作量更少,但仍然是相当数量的计算。

【讨论】:

  • 我从未见过存储每个不同双精度值的表。
  • @codekaizen:我也没有。我的意思是你的答案实现了你所拥有的。
  • 我看不出你怎么能在逻辑上实现这一点。给定一个值表并不意味着所有可能的值。片刻的反思应该会得出一个涵盖所有值的表格是不合理的。
  • 你有任何来源支持吗?我对此表示高度怀疑。这意味着计算例如sin(x) 的二阶导数在数值上为 0!如果将 x 映射到 [0..pi/4] 之间的值,计算 tayler 近似值会很快收敛
  • 这还不错 - 首先你只需要 0-45 度,因为对称。并且你可以使用身份从 sin(a)+sin(b) 中计算出 sin(a+b) 所以你只需要存储一个非常稀疏的表,
【解决方案4】:

如今,大多数三角函数都以查找表的形式实现。

【讨论】:

    【解决方案5】:

    您将得到的唯一真正答案是“个人资料”。

    很可能,如果这不是您代码中的瓶颈,那么它不会产生任何明显的差异。

    【讨论】:

      【解决方案6】:

      我对三角函数的经验是它们非常快,而且它们中的大多数无论如何都实现为lookup tables...也就是说,一些除法和除零检查可能会比调用三角函数要慢。

      【讨论】:

      • 比除法还快?我想这是在比较两个完全不同的东西,这就变成了架构细节的问题......如果它真的是一个查找表,那意味着我使用纯三角函数的旧方法更快,不是吗?
      • 我想是的,是的。但是,查找表需要内存访问,除非您在某个级别的缓存中遇到问题。
      • @aioobe,我很确定许多系统的查找表都是在芯片上实现的,因此不需要内存访问。我认为查找表中的错误是几年前臭名昭著的奔腾数学问题的原因。
      • @Jeffrey,你有那个数学问题的链接吗?
      • @aioobe: en.wikipedia.org/wiki/Pentium_FDIV_bug : "...在除法操作使用的查找表中缺少条目..."
      【解决方案7】:

      看看glibc。它使用了几种不同的实现,其中一些(如 sysdeps/ieee754/s_sin.c)看起来非常复杂,而另一些则使用汇编指令(如 sysdeps/x86_64/fpu/s_sincos.S)。如果不进行一些测量,很难说出实际所需的时间。

      【讨论】:

        【解决方案8】:

        评估三角函数的近似最优方法(以及通常使用的方法)是通过正交多项式展开(切比雪夫级数)。这样一个具有适当数量项的级数将比查找表更快。

        http://en.wikipedia.org/wiki/Chebyshev_polynomials

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-13
          • 1970-01-01
          • 2015-04-20
          • 1970-01-01
          • 2014-10-29
          • 1970-01-01
          • 1970-01-01
          • 2020-09-26
          相关资源
          最近更新 更多