2009-07-13 2 views
8

私は最近、Vector 3クラスを書いて、normalize()関数を友人にレビューするために提出しました。彼はそれは良いと言いましたが、CPU時間では "掛け算は分割よりも安い"ため、可能な限り逆数で乗算しなければなりません。分割するよりも安価に掛け合うのはなぜですか?

私の質問は単純に、なぜですか?

+1

intまたはfloatを扱っていますか? – Uri

+0

ベクトル3の場合、整数。どうして? – jkeys

+0

複製:http://stackoverflow.com/questions/655537/is-multiplying-the-inverse-better-or-worse – womp

答えて

9

は、そのハードウェアがより簡単に実装できる基本操作の面でそれについて考えてみよう。乗算は些細な設定であっても、そのような基本ステップは必要ありません。さらに、より高速な進歩アルゴリズムを提供します。たとえば、hereを参照してください。ただし、ハードウェアは一般的にそれらを利用しません。たとえば、ウィキペディアのURLによれば、「Toom-Cookは、5 N倍の掛け算のコストに対して、サイズNの3乗を行うことができます。これは、非常に高速です(Fürerのアルゴリズム、できますΘ(n ln(n) 2Θ(ln*(n))) - 再び、ウィキペディアのページとそこからのリンクを参照してください)。

部門はとして、intrisically遅くだけだ - 再び - wikipediaごとに、最良のアルゴリズム(HWで実装されているものもあります。なぜなら、乗算のための最高のアルゴリズムほど洗練されていない複雑な場所がないからです。)は、乗算のためのろうそくを保持できません。

それほど大きな数字ではない問題を数値化すると、便宜的には最新のものではありませんが、GMPの周りにある使いやすいPythonラッパーgmpyの結果があります。と最高のwheezes。プロ;-)第一世代(遅いMacBookの上:

$ python -mtimeit -s'import gmpy as g; a=g.mpf(198792823083408); b=g.mpf(7230824083); ib=1.0/b' 'a*ib' 
1000000 loops, best of 3: 0.186 usec per loop 
$ python -mtimeit -s'import gmpy as g; a=g.mpf(198792823083408); b=g.mpf(7230824083); ib=1.0/b' 'a/b' 
1000000 loops, best of 3: 0.276 usec per loop 

あなたも、この小さなサイズ(数字のビット数)で、まったく同じスピードに取り付か人によって最適化されたライブラリで、ご覧のよう逆数による乗算は、除算に要する時間の1/3を節約することができます。

それはこれらの数ナノ秒が生死の問題ですが、彼らをしているとき、そしてもちろん、あなたが繰り返し同じ値で除算されている場合は、その唯一のまれな状況であってもよい(1.0/bを離れて償却します操作!)、この知識は人生を節約することができます。

(同じ静脈で多く - x*xは、多くの場合、[PythonやFortranのような**「パワーに上げる」演算子を、持っている言語で] x**2に比べて時間を節約する - 多項式計算のためにとホーナーのscheme非常に好ましいです。電源投入操作が繰り返される! - )。あなたが戻って小学校に考えるならば、あなたはその乗算は加算と除算よりも硬くた思い出し

+0

[アセンブリ命令に関する有用な情報](http://www.agner.org/optimize/instruction_tables.pdf) – nonsensickle

0

(フロート)除算のCPU演算は、乗算よりもずっと複雑です。 CPUはもっと多くのことをしなければならない。私はハードウェアについては知識が豊富ですが、一般的な部門の実装についての情報はたくさんあります(たとえば、newton-raphsonアルゴリズムに基づいています)。

私はまた、常にCPUのパフォーマンスを得るために、代わりに分裂の逆数の乗算を使用について注意が必要になります。彼らはまったく同じ結果が得られない場合があります。これはあなたのアプリケーションによっては重要ではないかもしれません。追加、減算、シフト、比較 -

6

は、乗算よりも硬くしました。 CPUには何も変わりありません。

逆数の計算には除算が含まれているので、逆数を1回計算して3回使用しない限り、スピードアップは表示されません。

+3

+1は、相互にキャッシュする必要性に関する本質的な発言です。 – Thilo

+0

小学校では、加算よりも難しいことが分かりましたが、その2つは同じCPUのようです。 ;-) – Thilo

+0

@Thilo:減算を実行する必要があるときは、第2オペランドを無効にして、代わりに「より簡単に」追加できます。 :-) –