如何比较C++中log()和fp除法的性能?

Ven*_*hev 13 c++ floating-point performance logarithm

我在C++中使用基于日志的类来存储非常小的浮点值(因为这些值超出了范围double).由于我正在执行大量乘法运算,因此将乘法转换为和会带来额外的好处.

但是,在我的算法中的某个点,我需要将一个标准double值除以一个integer值,而不是一个*=基于日志的值.我已经*=为基于日志的类重载了运算符,并且右侧值首先通过运行转换为基于日志的值,log()然后添加到左侧值.因此,实际执行的操作是浮点除法log()和浮点求和.

我的问题是,首先将分母转换为基于对数的值会更快,这将用浮点减法替换浮点除法,产生以下操作链:两次log(),浮点减法,浮点数总和.

最后,这归结为浮点除法是快还是慢log().我怀疑一个常见的答案是这是依赖编译器和体系结构的,所以我会说我在darwin 10.3.0上使用Apple的gcc 4.2.不过,我希望得到一个关于这两个运算符的速度的一般性评论的答案和/或关于如何自己衡量差异的想法,因为这里可能会有更多,例如执行进行类型转换的构造函数等等

干杯!

Ste*_*non 12

你多次除以相同的整数吗?如果是这样,你可以乘以1./yourInteger,只做一次除法.如果可能的话,那会更快.

至于你的实际问题,它不仅依赖于编译器和体系结构,还依赖于微架构和数据.

在您的特定平台(darwin/x86)上,对于当前硬件i5/i7:分频(1)为~24个周期,log( )(2)为~35个周期.但是,因为除法仅使用单个指令调度槽,所以硬件的重新排序引擎可以在划分飞行时进行其他有用的计算; log( )相反,它是用软件实现的,因此处理器将其他计算提升到对数延迟的机会较少.这意味着在实践中,鸿沟通常会更快一些.

1)来自英特尔优化手册

2)通过log( )紧密循环调用并使用mach_absolute_time( )获取壁时间来测量.

  • @Ventzi:我挖出了我的"老化核心2二重奏"来做一些时间:35个循环用于划分,47个循环用于记录. (2认同)

Mar*_*n B 5

在x86架构上,对数显着长于分区:FYL2X的 85个周期(吞吐量)与FDIV的 40个周期相比.如果其他架构有很大不同,我会感到惊讶.与浮点除法一起使用.

  • darwin libm是开源的,分布在APSL下.不幸的是,`log`是以一种相当难以阅读的方式实现的(单个源文件支持`log`,`log2`,`log10`和`log1p`,所以你需要展开一堆预处理器符号来理解它).我会说最常用的速度"技巧"是:(1)它检测特殊情况而不需要任何浮点比较;(2)它使用矢量算法来减少核心多项式评估的延迟.http://opensource.apple.com/source/Libm/Libm-315/Source/Intel/log_universal.h (4认同)
  • gcc/darwin(他正在使用)使用SSE2进行双精度算术,而不是x87单位.`log`在软件中实现,divide使用`divsd`指令. (2认同)