我最感兴趣的是C / C ++中的“exp”和“exp2”函数,但这个问题可能与IEEE 754标准有关,而不是特定的语言特性。
在10年前的一个作业问题中,我试图按所需的周期,C函数对不同的浮点运算进行排序
double exp2 (double)
似乎比
略快double exp (double)
鉴于“double”使用尾数的二进制表示,我觉得这个结果是合理的。
然而,今天,在以几种不同的方式再次测试这两种方式之后,我看不出任何可衡量的差异。所以我的问题是
答案 0 :(得分:5)
有很多平台对他们的数学库不太关心,exp2(x)
简单地实现为exp(x * log(2))
,反之亦然。这些实现不能提供良好的准确性(或特别好的性能),但它们相当普遍。在这样做的平台上,一个函数与另一个函数一样昂贵,但是额外乘法的成本,无论哪个得到额外的乘法将是两者中较慢的。
在积极调整数学库并尝试提供良好准确性的平台上,这两个函数的性能非常相似。使用exp2
生成结果的指数更容易,但获得高精度有效数可能需要更多的工作;这两个因素大致均匀,即性能通常相当于10-15%。从广义上讲,exp2
通常是两者中较快的。
答案 1 :(得分:1)
是。
x86 FPU对非整数幂执行取幂的唯一方法是使用指令F2XM1
来计算 2 x -1 。
x86上不存在 e x 指令
x86的任何C库代码都被强制使用 2 x 来计算exp
和exp2
。
没有。
区别仅在于单个FPU乘法,这对于现代处理器来说非常快。
是。
15 - 20年前,乘法的价格远远高于其他业务的价格。如今,乘法几乎和加法一样便宜。
答案 2 :(得分:0)
我进行了一些测量,希望你们中的一些人会发现它有用。
-static -std=gnu++0x -ffast-math -Ofast -flto
#include <iostream>
#include <random>
#include <cmath>
#include <chrono>
using namespace std;
int main()
{
double g = 1/log(2);
mt19937 engine(1000);
uniform_real_distribution<double> u(0, 1);
double sum = 0;
auto begin = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 1e7/4; ++i) // for non-parallel, `for (int i = 0; i < 1e7; ++i)`
{
sum += exp2(u(engine)*g); // for exp versions, sum += exp(u(engine)); for empty version, sum += u(engine)
sum += exp2(u(engine)*g); // removed for non-parallel
sum += exp2(u(engine)*g); // removed for non-parallel
sum += exp2(u(engine)*g); // removed for non-parallel
}
auto end = std::chrono::high_resolution_clock::now();
cout << chrono::duration_cast<chrono::nanoseconds>(end - begin).count()/1000./1000 << "ms" << "\t"
<< sum << "\t" << g << " exp2 p4" << endl;
}
执行:
for i in {1..100}; do ./exp2_p4.bin && ./exp_p4.bin && ./exp.bin && ./exp2.bin; done
下表显示了平均运行时间(时间),以毫秒为单位的标准偏差和最快的情况。
| name | time (ms) | std (ms) | smallest (ms) |
|:-------:|:---------:|:--------:|:-------------:|
| empty | 244.7 | 26.2 | 130.9 |
| exp | 591.7 | 95.8 | 422.5 |
| exp2 | 536.5 | 85.4 | 393.7 |
| exp p4 | 612.3 | 89.6 | 433.2 |
| exp2 p4 | 557.2 | 87.6 | 396.8 |
对于一项操作,需要将其除以1e7
。我通过从指数版本中减去空版本的时间来估算指数成本。这些值如下所示:
-ffast-math
,exp2也可以比使用gcc的Intel Xeon上的exp快11%。