这个问题源于一个单独的问题 https://stackoverflow.com/questions/43033593/why-is-using-tanh-definition-of-logistic-sigmoid-faster-than-scipys-expit,结果证明它有一些明显的机器特定的怪癖。当我运行下面列出的 C++ 代码来记录之间的计时差异时tanh
and exp
,我看到以下结果:
tanh: 5.22203
exp: 14.9393
tanh
运行速度约为 3 倍exp
。考虑到数学定义,这有点令人惊讶tanh
(并且不了解所实现的算法定义)。
更重要的是,这种情况发生在我的笔记本电脑上(Ubuntu 16.04,Intel Core i7-3517U CPU @ 1.90GHz × 4),但不会发生在我的台式机上(相同的操作系统,目前不确定CPU规格)。
我编译了下面的代码g++
。上述时间没有编译器优化,尽管如果我使用的话趋势仍然存在-On
对于每个n
。我也摆弄过a
and b
值来查看正在评估的值范围是否产生影响。这似乎并不重要。
什么会导致tanh
比exp
在不同的机器上?
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
int main() {
double a = -5;
double b = 5;
int N = 10001;
double x[10001];
double y[10001];
double h = (b-a) / (N-1);
clock_t begin, end;
for(int i=0; i < N; i++)
x[i] = a + i*h;
begin = clock();
for(int i=0; i < N; i++)
for(int j=0; j < N; j++)
y[i] = tanh(x[i]);
end = clock();
cout << "tanh: " << double(end - begin) / CLOCKS_PER_SEC << "\n";
begin = clock();
for(int i=0; i < N; i++)
for(int j=0; j < N; j++)
y[i] = exp(x[i]);
end = clock();
cout << "exp: " << double(end - begin) / CLOCKS_PER_SEC << "\n";
return 0;
}
编辑:一些汇编输出
这是输出 https://pastebin.com/6BD7nzsk当我编译下面的简化代码时g++ -g -O -Wa,-aslh nothing2.cpp > stuff.txt
.
#include <cmath>
int main() {
double x = 0.0;
double y,z;
y = tanh(x);
z = exp(x);
return 0;
}
编辑:另一个更新
Assume nothing2.cpp
包含先前编辑中的简化代码。我跑:
g++ -o nothing2.so -shared -fPIC nothing2.cpp
objdump -d nothing2.so > stuff.txt
这是内容stuff.txt https://pastebin.com/DvEqrNn0