15

C ++でログベースのクラスを使用して、非常に小さな浮動小数点値を格納しています(値が範囲を超えているためdouble)。多数の乗算を実行しているので、これには乗算を合計に変換するという追加の利点があります。

ただし、アルゴリズムの特定の時点で、標準double値を値で除算する必要があり、ログベースのinteger*=に除算する必要があります。ログベースのクラスの演算子をオーバーロードしまし*=た。右側の値は、実行によって最初にログベースの値に変換されてlog()から、左側の値に追加されます。したがって、実際に実行される演算は、浮動小数点除算log()と浮動小数点加算です。

最初に分母をログベースの値に変換する方が速いかどうかという私の質問です。これにより、浮動小数点除算が浮動小数点減算に置き換えられ、次の一連の演算が生成されます:2回log()、浮動小数点減算、浮動小数点合計。

結局、これは、浮動小数点除算が。より速いか遅いかに要約されますlog()。一般的な答えは、これはコンパイラとアーキテクチャに依存していると思われるので、ダーウィン10.3.0でAppleのgcc4.2を使用していると言います。それでも、型変換を行うコンストラクターを実行するなど、ここでさらに多くのことが行われる可能性があるため、これら2つの演算子の速度に関する一般的な意見や、違いを自分で測定する方法についてのアイデアを得たいと思います。等

乾杯!

4

4 に答える 4

17

同じ整数で複数回割りますか? その場合は、代わりに を掛けて1./yourInteger、除算を 1 回だけ行うことができます。可能であれば、どちらよりも高速です。

実際の質問に関しては、コンパイラとアーキテクチャに依存するだけでなく、マイクロアーキテクチャとデータにも依存します。

特定のプラットフォーム (darwin/x86) で、現在のハードウェア i5/i7 の場合: 除算 (1) で ~24 サイクル、log( )(2) で ~35 サイクル。ただし、除算では命令ディスパッチ スロットが 1 つしか使用されないため、ハードウェアの並べ替えエンジンは、除算の進行中に他の有用な計算を実行できます。log( )対照的に、ソフトウェアで実装されているため、プロセッサが他の計算を対数のレイテンシに引き上げる機会は少なくなります。これは、実際には、除算がかなり高速になることが多いことを意味します。

1) インテル最適化マニュアルより

log( )2)タイトなループで呼び出し、mach_absolute_time( )ウォール タイムを取得するために使用して測定。

于 2010-05-18T19:26:16.420 に答える
5

x86 アーキテクチャでは、対数は除算よりも大幅に時間がかかります。 FDIVの 40 サイクルと比較して、 FYL2Xの 85 サイクル (スループット) です。他のアーキテクチャが大きく異なる場合、私は驚くでしょう。浮動小数点除算を使用します。

于 2010-05-18T17:37:03.517 に答える
1

どんなアルゴリズムでも対数計算を行うと、FP分割よりもかなりコストがかかると確信しています。

もちろん、確実にする唯一の方法は、それをコード化して、コードのパフォーマンスを測定することです。あなたの説明から、両方のバージョンを実装して並べて試すのはそれほど難しいことではないように思えます。

于 2010-05-18T17:20:06.663 に答える
1

除算の主な問題は、最近のほとんどの CPU では単一の命令ですが、通常は高いlatency(PowerPC では 31 サイクル - x86 では何があるかわかりません) ことです。ただし、分割と同時に発行できる他の非依存命令がある場合、このレイテンシの一部を埋めることができます。したがって、答えは、分割を含むループ内の命令の組み合わせと依存関係の種類によって多少異なります (使用している CPU は言うまでもありません)。

そうは言っても、ほとんどのアーキテクチャでは、除算は対数関数よりも高速になるというのが私の直感です。

于 2010-05-18T16:14:01.103 に答える