関数の速度(1)

私はいつも実行速度と戦っている。
遅さの原因がどこにあるかと探ると、
そこにはたいてい atan2 がある。
テーブルを作って速くしたりしているが、劇的には速くならない。
やはり肝心なのはatan2を使わないこと。
atan2の使用を避ける方法をいつも考えている。


だから、atan2/sin/cosあたりの速度はよく知っている。
だが、ほかの組込み関数はどうだろうと思い調べてみた。
コンパイラは、VC2005EE。
オプションはreleaseのデフォルト(最適化は/O2)。
コードは下。


xを0.5〜1.5の間で変化させて関数の和をとる。
繰り返し回数は適当に変えて、


sum += y;

のときの時間との差をとって、1回あたりの時間を測った。

exp(x) 35ns
sin(x) 45ns
cos(x) 45ns
log(x) 43ns
atan(x) 87ns
atan2(x,1) 137ns
sqrt(x) 23ns
pow(x,2) 4.0ns
pow(x,2.1) 108ns
x*x 0.17ns
x*x*x 0.72ns
x/3 13ns

色々思うところはあるが、次回以降に回して、
最後のところ、
割り算が異様に遅い。
しかし、定数で割るのなら、
こうすれば掛け算になって速くなる。


sum += y * (1.0 / 3);



#include
#include
#include

using namespace std;

void bench_exp();

const int N = (int)1e8;
const double dx = 1.0 / N;

void main(void) {
bench_exp();
}

void bench_exp() {
int t = timeGetTime();

double sum = 0;
double x = 0.5;
for(int i = 0; i < N; i++) {
sum += exp(x); // ←ここを変える
x += dx;
}

fprintf(stdout, "%.3fs\n", (timeGetTime() - t) * 1e-3);
fprintf(stdout, "%e\n", sum);
}