众所周知,用于乘法的处理器指令所需的时间比加法多几倍,除法甚至更差(UPD:不再适用,见下文)。那些更复杂的操作如指数呢?他们有多困难?
动机即可。我感兴趣,因为它有助于算法设计在早期阶段估计算法的性能关键部分。假设我想对图像应用一组过滤器。其中一个在每个像素的3×3邻域上运行,将它们相加并取得atan。另一个相加较多的相邻像素,但不使用复杂的功能。哪一个会执行更长时间?
所以,理想情况下我希望得到基本运算执行的近似相对时间,比如乘法通常需要比加法多5倍的时间,指数大约是100次乘法。当然,这是一个数量级的协议,而不是确切的值。我知道它取决于硬件和参数,所以我们说我们测量现代x86 / x64上浮点运算的平均时间(在某种意义上)。对于未在硬件中实现的操作,我对C ++标准库的典型运行时间感兴趣。
在分析此类内容时,您是否看到过任何来源?这个问题有意义吗?或者没有像这样的经验法则可以在实践中应用?
答案 0 :(得分:8)
首先,让我们清楚。这样:
众所周知,乘法处理器指令需要 比添加时间多几倍
一般不再是真的。许多年都不是这样,需要不再重复。在大多数常见架构中,整数乘法是几个周期,整数加法是单周期;浮点加法和乘法往往具有几乎相等的时序特性(通常大约4-6个周期的延迟,具有单周期吞吐量)。
现在,对于您的实际问题:它随架构和实现而变化。在最近的架构中,有一个编写良好的数学库,像exp
和log
这样的简单基本函数通常需要几十个周期(20-50个周期是一个合理的背后数字图)。使用质量较低的库,您有时会看到这些操作需要几百个周期。
对于更复杂的功能,例如pow
,典型的时间范围从高几十到几百个周期。
答案 1 :(得分:2)
你不应该担心这个。如果我告诉你,超常函数的典型C库实现往往需要大约10倍的单浮点加法/乘法(或50浮点加法/乘法),并且大约是浮点除法的5倍,这不会是对你有用。
事实上,处理器调度内存访问的方式会严重干扰您所做的任何过早优化。
如果在分析后发现使用超越函数的特定实现太慢,您可以考虑设置多项式插值方案。这将包括一个表,因此会产生额外的缓存问题,因此请确保测量而不是猜测。
这可能涉及Chebyshev approximation。记录下来,这是一种特别有用的技术。
我被告知编译器在优化浮点代码方面非常糟糕。您可能想要编写自定义汇编代码。
此外,Intel Performance Primitives(如果您使用的是英特尔CPU)如果您准备以一定的准确度来换取速度,那么它就是一件好事。
答案 2 :(得分:0)
您可以随时启动第二个线程并为操作计时。大多数基本操作在执行时间上没有那么大的差别。最大的区别是执行的次数。 O(n)通常是你应该考虑的。