三角函数计算在计算机中是否代价高昂?

28

我在某篇文章中读到,三角函数计算通常很耗费时间。这是真的吗?如果是,这就是为什么使用三角函数查找表的原因,对吗?

编辑:嗯,那么如果唯一变化的只是角度(精确到1度),是否使用360个记录每个角度的查找表会更快?


4
查找表在旧的微处理器上经常使用,比如一个机器人臂的8位CPU,它没有硬件浮点运算或乘法(在某些情况下是6502)。现在,速度优势已不再像以前那样重要。 - David Thornley
1
技术进步万岁 :) - Dominic K
8个回答

22

昂贵是一个相对的术语。

最快执行的数学操作是那些可以直接由处理器执行的操作。当然整数加法和减法将是其中之一。根据处理器,可能还有乘法和除法。有时处理器(或协处理器)可以原生地处理浮点运算。

更复杂的事情(例如平方根)需要执行一系列这些低级别的计算。通常使用数学库来完成这些操作(建立在处理器可以执行的本地操作之上)。

所有这些现在都发生得非常非常快,因此“昂贵”取决于您需要做多少,并且您需要它发生的速度有多快。

如果您正在编写实时3D渲染软件,则可能需要使用大量巧妙的数学技巧和快捷方式,以从环境中挤出每一位速度。

如果您正在处理典型的业务应用程序,则很可能您所做的数学计算不会对系统的整体性能产生重大影响。


4
实际上,平方根非常普遍,因此经常在硬件中实现。对于更复杂的函数(例如三角函数),虽然有一些架构曾经实现过它们(x87 是最广为人知的),但并没有太多好处。 - slacker
3
当你说“in hardware”时,是指FSQRT只需少量的时钟周期,还是仅表示它是一条单指令并在纳米/微代码中实现的?我知道有针对平方根功能的硬件设计,但我认为它们不在大多数处理器中。 - NVRAM

19

在Intel x86处理器上,浮点数加减需要6个时钟周期,乘法需要8个时钟周期,而除法需要30-44个时钟周期。但余弦函数需要180到280个时钟周期。

虽然x86处理器可通过硬件执行这些操作,速度仍然很快,但比更基本的数学函数慢得多。


16
实际上,这些信息已经相当过时了。现在,FP加法需要3-4个周期,FP乘法需要4-5个周期,这取决于处理器。请注意,这些操作完全是流水线化的,因此您可以在每个时钟周期开始一个新的加法和乘法计算。除法通常需要20-25个周期,并且不能进行流水线化处理。如果被除数足够接近除数,则较新的处理器也可以提前终止除法运算 - 在某些情况下只需6个周期。 - slacker
3
除非您在谈论奔腾4,否则就是它做任何事情都很慢。显然。 - slacker

8

由于sin()、cos()和tan()是通过求和数列计算得出的数学函数,因此开发者有时会使用查找表来避免昂贵的计算。

这种做法需要权衡精度和内存。精度要求越高,所需的查找表内存就越大。

请看下面这张精确到1度的表格。

http://www.analyzemath.com/trigonometry/trig_1.gif


2
所有浮点运算都非常耗费资源。即使是加法,也需要进行大量的比较、整数相加和位移操作。当然,这要比 sin、cos、tan 要便宜得多。 - kennytm
1
@Kenny - 是的,你说得对,因为它们本质上不被表示为整数 :) - Codebrain
3
不对。它们确实比整数操作慢,但并不是那么慢。在典型的现代CPU上,浮点加法通常需要3个时钟周期。sin()函数需要大约200个周期(取决于CPU和方法)。我希望你看出了区别? - slacker
1
@Codebrain, KennyTM:在x86架构上,你可能是正确的(我不熟悉x86上的指令延迟)。然而,支持浮点数的其他嵌入式处理器可以以与整数单元相同的延迟生成FP结果。因此,并不一定是“本质上不能表示为整数”的问题。实际上,在优化的硬件上,到某种程度上说,两个24位数(FP的尾数部分)的乘法比两个32位整数的乘法更快。使用小加法器并行执行指数字段的加法和尾数的乘法。 - ysap
4
考虑到缓存的影响,查找时间会有所不同。通常情况下,项目不在缓存中,这意味着查找将需要完整的 RAM 访问时间 - 这将需要很多时钟周期。您可能会发现浮点指令比查找快。 - Mark Ransom
显示剩余2条评论

3
是的,(相对于其他数学运算如乘法和除法)如果你正在进行实时操作(矩阵运算,视频游戏等),通过将三角函数计算移出内部循环,可以节省大量周期。
如果你不是在进行实时操作,那么相对来说它们并不昂贵(相对于从磁盘读取大量数据、生成网页等操作)。希望你的CPU通过硬件完成三角函数运算(每秒可以执行数十亿次浮点运算)。

1
除了x86 CPU,我不知道任何CPU架构,无论是内置协处理器(PPC)还是外部协处理器(ARM),都可以在硬件中执行三角函数运算。即使是x86 CPU也不会真正地在硬件中执行它们,它们提供一个操作码来执行它们,但在内部运行微代码,根据简单的算术(如加、减、乘和除法)计算这些值。GPU可能可以,但对于CPU来说,三角函数运算非常罕见。 - Mecki

2

虽然简单的数学函数(如加法/乘法/减法等)比这些高级函数更便宜,但从人类时间的角度来看,他们并不“昂贵”。通常人们通过查表和逼近来优化这些函数是因为他们每秒可能被调用数万次,而每微秒都很有价值。

如果你正在编写一个程序,只需要每秒调用几次函数,则内置函数足够快。


2

我建议您编写一个测试程序并自行计时。是的,与加减法相比,它们很慢,但它们仍然是单处理器指令。除非您正在执行数百万次迭代的非常紧密的循环,否则这不太可能成为问题。


1
如果您始终知道要计算的角度,可以将它们存储在变量中,而不是每次都重新计算。这也适用于您的方法/函数调用,在其中角度不会改变的情况下。您可以聪明地使用一些公式(从sin(theta/2)计算sin(theta),知道值重复的频率- sin(theta + 2*pi*n) = sin(theta)),以减少计算量。请参见this维基百科文章。

0

是的。三角函数是通过求和一系列计算得出的。因此,一般来说,它比简单的数学运算要昂贵得多。平方根也是如此。


6
泰勒展开不是现代浮点运算器计算三角函数的方法。它们使用迭代逼近法,每次迭代可以提供比泰勒级数更多的有效数字位数。这些迭代逼近法比CORDIC更为常见,在嵌入式应用中空间比速度更为重要时才会使用CORDIC。 - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接