C/ c++最快的cmath日志操作
C/C++ fastest cmath log operation
我试图计算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)。
由于b
和a
是整数,您可以使用所有的位旋转来找到它们的以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
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- cmath抛出错误C2062、C2059、C2143和C2447.cmath包含在矢量文件中
- 更新到莫哈韦后出现cmath错误
- cmath 是否借用了 math.h 的实现
- 是否可以配置提升日志刷新?
- 跟踪日志中的T.11803()是什么意思?
- 加快在C++中读取/处理日志文件的速度
- 如何将消息时间戳写入日志文件?
- 分析包含 NMEA 句子的日志文件C++
- 如何修复输出日志中的"EnableInput can only be specified on a Pawn for its Controller"错误
- 如何实现具有多个平台__FILE__和__LINE__信息的 C/C++ 可变参数日志记录宏?
- Log4net,将日志消息从 c++ dll 发送到 c# 应用程序?
- 返回ERROR_INVALID_PARAMETER的事件日志函数
- 为什么系统日志有两个不同的函数声明?
- 从更改日志获取最新的 USN 数据
- 如何从日志文件中抓取状态代码?(在 C++ 中)
- 未创建日志文件
- C++ 中混合二进制/文本日志记录的最佳做法
- 将日志宏转换为目标 C 字符串
- C/ c++最快的cmath日志操作