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

C/C++ fastest cmath log operation

本文关键字:cmath 日志 操作 c++      更新时间:2023-10-16

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

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

Edit:我最初说自然对数(以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为基数的log函数,这解释了为什么我不熟悉它。此外,用于计算日志的x86指令包括自动乘法,并且不同基数所需的常量也可以通过优化指令获得,因此我希望3种不同的日志函数具有相同的计时(即使基数2也必须乘以1)。

由于ba是整数,您可以使用所有的位旋转来找到它们的以2为底的日志。以下是一些:

  • 在O(N)次操作(最明显的方法)中找到以2为底的整数的logb N
  • 查找64位IEEE浮点数
  • 的整数以2为底的整数对数
  • 用查找表查找以2为基数的整数
  • 在O(lg(N))次运算中求N位整数以2为底的对数
  • 用乘法和查找在O(lg(N))次运算中找到N位整数的log以2为底的对数

我把它留给你选择最好的"快速日志"功能根据你的需要。

在我有数据的平台上,log2比其他平台稍微快一些,符合我的期望。但是请注意,差异非常微小(只有几个百分点)。这真的不值得担心。

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

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

当然,这类问题在很大程度上取决于您的处理器/体系结构,所以我建议做一个简单的测试并计时。

答案是:

  • 这取决于
  • 概要文件它

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

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

如果你真的想,你可以使用CUDA和GPU。

我想,如果你很不幸地缺少这些指令集,你可以在位摆弄水平上写一个算法来做一个很好的近似。在这种情况下,我可以赌不止一个苹果派2-log会比其他任何base-log