- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我目前正在尝试优化一些代码,其中 50% 的时间花费在 std::pow()
上。我知道指数将始终 为正整数,而底数将始终为区间 (0, 1) 中的 double 。为了好玩,我写了一个函数:
inline double int_pow(double base, int exponent)
{
double out = 1.0;
for(int i = 0; i < exponent; i++)
{
out *= base;
}
return out;
}
我正在编译:
> g++ fast-pow.cpp -O3 --std=c++11
我在 (0, 1) 之间生成了 1 亿个 double ,并比较了 (1) std::pow
(2) 我自制的 int_pow
函数的时间以及(3)直接乘法。这是我的计时程序的草图(这是一个非常快速的组合测试):
void time_me(int exp, size_t reps)
{
volatile double foo = 0.0;
double base = 0.0;
size_t i;
for (i = 0; i < reps; ++i)
{
base = ((double) rand() / (RAND_MAX)) + 1;
foo = pow(base, exp);
// foo = int_pow(base, exp);
// foo = base * base * base;
}
// check that the loop made it to the end
std::cout << foo << " " << i << std::endl;
}
int main()
{
std::clock_t start;
start = std::clock();
time_me(3, 1e8);
std::cout << "Time: " << (std::clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << std::endl;
return 0;
}
以下是我观察到的各种指数的时间:
std::pow
0.71s, int_pow
0.77sstd::pow
1.31s, int_pow
0.80s, direct mult 0.86sstd::pow
6.9s (!!), int_pow
0.84s, 直接mult 0.76秒因此,我的问题是:
std::pow
的性能对于大于 2 的幂似乎下降得如此严重? std::pow
来处理已知整数指数的情况,并且不想错过一些完全微不足道的事情。谢谢!!
最佳答案
std::pow()
是一个通用函数,旨在接受任何一对浮点值。它执行昂贵的计算,应该被认为是一个慢函数。然而,显然,很多人滥用它来求平方,因此 IBM Accurate Mathematical Library(由 glibc 使用)中的 pow()
的实现针对该特定情况进行了优化:
sysdeps/ieee754/dbl-64/e_pow.c :
double
__ieee754_pow (double x, double y)
{
...
...
if (y == 1.0)
return x;
if (y == 2.0)
return x * x;
if (y == -1.0)
return 1.0 / x;
if (y == 0)
return 1.0;
如您所见,指数值 0、1 和 -1 也经过特殊处理,但至少这些是数学上重要的特殊情况,而平方只是统计上重要的情况,否则不应该进行特殊处理). 编辑:指数值0
、1
、2
和-1
是只有那些允许使用(更快的)算术运算来表达 std::pow(x,n)
而不会损失任何准确性的。参见 this answer更多细节。因此 2
的指数值不仅仅是一个具有统计意义的案例。 结束编辑
如果您想要一个快速替代 std::pow()
的指数的非负整数值并且不关心轻微的精度损失,那么
必须通过仔细的基准测试找到用于在第一种方法和第二种方法之间进行选择的指数的边界值。
关于c++ - std::pow 不同指数的行为非常不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38060139/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
我发现了 pow(x, n) 的迭代实现,它需要 o(log n) 时间和常量空间,如下所示: double pow(double x, int n) { double left = x;
我想创建一个特征,说它实现了num_traits::pow::Pow - Rust。 我的特征当前定义为: pub trait PrimeSieveTrait: AddAssign + MulAs
对于我的项目,我应该在 java 中创建一个图形计算器(绘制图形),并以函数作为输入。我已经找到了一种正确绘制函数图的方法。但是我想不出一种方法可以让解释器理解该功能。如果我能够做到这一点,以便我可以
我发现对于大整数,math.pow() 没有成功给出它的整数版本。 (我在使用 math.pow 实现时遇到了一个错误 Karatsuba multiplication)。 例如: >>> a_Siz
问题或多或少说明了一切。 calling a host function("std::pow ") from a __device__/__global__ function("_calc_psd")
我想知道,因为当我在检查模式下运行我的代码时,似乎出现了一些差异。例如: List getFactors(int n) { List factors = [[1, n]]; doubl
pow(a/b,x) 和 pow(b/a,-x) 在精度上有区别吗?如果存在,将小于 1 的数字提升为正幂或将大于 1 的数字提升为负幂会产生更准确的结果吗? 编辑:让我们假设 x86_64 处理器和
此代码在 Windows 上的 Visual Studio 2010 上正确编译,但我在 Linux、g++ 上遇到此错误。谁能解释一下如何解决这个问题? int bits; T scale; std
Python内置的pow(x, y)(没有第三个参数)返回的结果和math.pow()返回的值有区别吗>,在两个 float 参数的情况下。 我问这个问题是因为 documentation对于 mat
这个问题在这里已经有了答案: Why was std::pow(double, int) removed from C++11? (1 个回答) 关闭 9 年前。 在 C++ 03 中,使用例如st
我可以将pow()与#include 一起使用,而无需使用using关键字或::运算符。为什么? 最佳答案 来自标准的[headers]/4。 Except as noted in Clause 20
我觉得这很有趣: System.out.println( (long)(Math.pow(2,63) - 1) == Long.MAX_VALUE); // true System.out.prin
这个打印 100: int j=2; int i= pow(10,2); printf("%d\n", i); 这个打印出 99: int j=2; int i= pow(10,j); print
这也是一个与数学相关的问题,但我想用 C++ 实现它...所以,我有一个 2^n 形式的数字,我必须计算它的数字总和(以 10 为基数;P)。我的想法是用下面的公式来计算: sum = (2^n mo
我看到这个关于 std::pow 的老问题:What is more efficient? Using pow to square or just multiply it with itself? 旧
我正在尝试比较 pow(x,2.0) 和 pow(x,2.0000001) 的性能,但我认为 2.0 会快得多,但它们的速度相同。我什至通过使用 -Xint 参数运行 jar 来删除 JIT 优化。
我的 linux 版本是 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64 GNU/Linux我的 gcc 版本是
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 6 年前。 Improve t
python3 中的 pow() 函数提供指数的值。 >>>pow(2,3) 8 Python3 支持负指数,即 可以使用 pow(10,-1) 表示。当我计算 pow(4,-1,5) 时,它给出了输
我是一名优秀的程序员,十分优秀!