C / C ++最快的cmath日志操作

时间:2011-07-11 20:05:38

标签: c++ c logarithm math.h cmath

我正在尝试计算log a b(并获得一个浮点,而不是一个整数)。我计划将此作为log(b)/log(a)。从数学上讲,我可以使用任何cmath对数函数(基数2,e或10)来进行计算;但是,我会在我的程序中运行这个计算很多,所以我想知道其中一个是否比其他程序快得多(或者更好的是,如果有更快,但仍然很简单的方法)。如果重要,a和b都是整数。

5 个答案:

答案 0 :(得分:15)

首先,预先计算1.0/log(a)并将每个log(b)乘以该表达式。

编辑:我原先说自然对数(基数e)会最快,但其他人说基数2直接由处理器支持并且速度最快。我没有理由怀疑它。

编辑2:我原先认为a是一个常数,但重新阅读了从未说过的问题。如果是这样,那么预先计算将没有任何好处。但是,如果是这样,您可以通过适当选择变量名来保持可读性:

const double base_a = 1.0 / log(a);
for (int b = 0; b < bazillions; ++b)
    double result = log(b) * base_a;

奇怪的是,微软没有提供基本2日志功能,这解释了为什么我不熟悉它。此外x86 instruction for calculating logs自动包含乘法,不同基数所需的常数也可以通过optimized instruction获得,所以我希望3个不同的日志函数具有相同的时序(即使是2的基数也是如此)必须乘以1)。

答案 1 :(得分:11)

由于ba是整数,因此您可以使用bit twiddling的所有荣耀来查找基数2的日志。以下是一些:

  • 在O(N)操作中设置MSB N的整数的日志库2(显而易见的方式)
  • 查找具有64位IEEE float
  • 的整数的整数对数基数2
  • 查找带有查找表的整数的日志库2
  • 在O(lg(N))操作
  • 中查找N位整数的对数库2
  • 使用乘法和查找在O(lg(N))运算中查找N位整数的对数基数

我会留给您选择最适合您需求的“快速日志”功能。

答案 2 :(得分:4)

在我拥有数据的平台上,log2比其他平台快一点,符合我的期望。但请注意,差异轻微(仅百分之几)。这真的不值得担心。

编写一个清晰的实现。然后测量性能。

答案 3 :(得分:1)

在8087指令集中,只有对数为2的对数指令,所以我猜这个指令是最快的。

当然,这类问题在很大程度上取决于您的处理器/架构,因此我建议您进行简单的测试并计算时间。

答案 4 :(得分:0)

答案是:

  • 取决于
  • 个人资料

您甚至没有提到您的CPU类型,变量类型,编译器标志,数据布局。如果您需要并行完成这些操作,我相信会有SIMD选项。只要您使用对齐并清除简单循环(或者如果您喜欢古老的方法则为valarray),您的编译器优化它。

很可能,英特尔编译器在这方面对英特尔处理器有特定的技巧。

如果你真的想要你可以使用CUDA并利用GPU。

我想,如果你不幸缺少这些指令集you could go down at the bit fiddling level并编写一个does a nice approximation的算法。在这种情况下,我可以打赌不止一个苹果派,2-log将比任何其他基本日志更快