pow()関数は通常、数学ライブラリに実装され、場合によってはターゲットプロセッサで特別な命令を使用し ます。x86の場合は、「方法:x86のpow(real、real)」を参照してください。ただし、やなどの命令fyl2x
はf2xm1
高速ではないため、全体で100CPUサイクルかかる可能性があります。パフォーマンス上の理由から、gccのようなコンパイラーは、特別な場合に計算をより高速に実行するための強度低下を提供する「組み込み」関数を提供します。累乗N
が整数(あなたの場合のように)で小さく(あなたの場合のように)である場合N
、ライブラリ関数を呼び出すよりも時間を乗算する方が高速です。
累乗が整数である場合を検出するために、数学ライブラリは、たとえば、オーバーロードされた関数を提供しますdouble pow(double,int)
。gccが変換することがわかります
double x = std::pow(y,4);
内部的に2つの乗算になります。これは、ライブラリ呼び出しよりもはるかに高速で、両方のオペランドが整数の場合に期待する正確な整数の結果を提供します。
double tmp = y * y;
double x = tmp * tmp;
このタイプの強度低下を取得するには、
<cmath>を含める
- 最適化-O2でコンパイル
- ライブラリ内のpow関数を明示的に呼び出して、
std::pow()
それがmath.hからのバージョンではなく、取得したバージョンであることを確認します。
次に、次のように見える<cmath>のオーバーロードされたpow関数を照合します。
inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); }
__builtin_powi
この関数は、累乗が小さい整数の場合に、pow()の乗算への強度低下を認識して実装されていることに注意してください。