基本函数的典型执行时间

Typical time of execution for elementary functions

本文关键字:典型 执行时间 函数      更新时间:2023-10-16

众所周知,处理器指令执行乘法要比执行加法多花好几倍的时间,而执行除法则更糟糕(UPD:这已经不再是事实了,见下文)。那么更复杂的运算,比如指数呢?它们有多难?

。我很感兴趣,因为它有助于算法设计,在早期阶段估计算法的性能关键部分。假设我想对图像应用一组滤镜。其中一种方法是对每个像素的3×3邻域进行操作,对它们求和,然后取atan。另一种算法对更多相邻像素求和,但不使用复杂的函数。哪一个执行时间更长?

所以,理想情况下,我想要有基本运算执行的近似相对时间,比如乘法通常比加法多花5倍的时间,指数大约是100次乘法。当然,这是一个数量级的交易,而不是确切的值。我知道这取决于硬件和参数,所以假设我们测量现代x86/x64上浮点操作的平均时间(在某种意义上)。对于没有在硬件中实现的操作,我对c++标准库的典型运行时间感兴趣。

在分析这类东西时,你有没有看到任何资料来源?这个问题有意义吗?或者没有这样的经验法则可以在实践中应用?

首先,让我们弄清楚。:

众所周知,用于乘法运算的处理器指令需要数倍于加法的时间

一般来说

不再为真。很多很多年都不是这样,需要停止重复。在大多数常见的体系结构中,整数乘法是一对周期,整数加法是单周期;浮点加法和乘法往往具有几乎相等的时间特性(通常约为4-6个周期的延迟,具有单周期吞吐量)。

现在,对于您的实际问题:它随体系结构和实现而变化。在最近的体系结构中,有一个编写良好的数学库,像explog这样的简单基本函数通常需要几十个周期(20-50个周期是一个合理的粗略数字)。对于质量较低的库,您有时会看到这些操作需要几百个周期。

对于更复杂的函数,如pow,典型的计时范围从几十到几百个周期。

你不应该担心这个。如果我告诉你,一个典型的超越函数的C库实现往往需要大约10次浮点加法/乘法(或50次浮点加法/乘法),大约5次浮点除法,这对你来说是没有用的。

实际上,处理器调度内存访问的方式将严重干扰您所做的任何过早优化。

如果在分析之后,您发现使用超越函数的特定实现太慢,您可以考虑设置一个多项式插值方案。这将包含一个表,因此会导致额外的缓存问题,所以请确保测量而不是猜测。

这可能涉及到切比雪夫近似。在这类领域,这是一项特别有用的技术。

有人告诉我编译器在优化浮点代码方面非常糟糕。您可能想编写自定义汇编代码。

此外,如果你准备牺牲一些精度来换取速度,那么英特尔性能原语(如果你使用英特尔CPU)是值得拥有的。

您总是可以启动第二个线程并计时操作。大多数基本操作在执行时间上没有太大差别。最大的区别是执行了多少次。O(n)通常是你应该考虑的。