web-dev-qa-db-ja.com

除算が乗算よりも高価なのはなぜですか?

私は本当に何かを最適化しようとしているわけではありませんが、プログラマーからこれを真実と受け止めたといつも聞いていたのを覚えています。結局、彼らはこのことを知っているはずです。

しかし、除算が乗算よりも実際に遅いのはなぜですか?除算は見事な減算ではなく、乗算は見事な加算です。だから数学的には、なぜ一方通行が計算上非常に異なるコストになるのかわかりません。

誰かがこれの理由/原因を明確にしてくれるので、私が知っているので、私が以前に尋ねた他のプログラマーから聞いたものの代わりに、「理由」です。

39
Joan Venge

CPUの [〜#〜] alu [〜#〜] (算術論理演算ユニット)はアルゴリズムを実行しますが、ハードウェアに実装されています。古典的な乗算アルゴリズムには Wallace tree および Dadda tree が含まれます。詳細は こちら をご覧ください。新しいプロセッサーでは、より高度な手法を利用できます。一般に、プロセッサは、必要なクロックサイクルを最小限に抑えるために、ビットペアの操作を並列化するように努めています。乗算アルゴリズムは非常に効果的に並列化できます(ただし、より多くのトランジスタが必要です)。

除算アルゴリズム は効率的に並列化できません。最も効率的な除算アルゴリズムは非常に複雑です( Pentium FDIVバグ は複雑さのレベルを示しています)。一般に、ビットあたりのクロックサイクルが多く必要です。技術的な詳細が必要な場合は、 here がIntelからの素晴らしい説明です。 Intelは実際には 特許 除算アルゴリズムです。

50
Lior Kogan

しかし、除算が乗算よりも実際に遅いのはなぜですか?除算は見事な減算ではなく、乗算は見事な加算です。

大きな違いは、長い乗算では、シフトとマスキングの後に一連の数値を足すだけでよいということです。長い除算では、減算ごとにオーバーフローをテストする必要があります。


2つのnビット2進数の長い乗算を考えてみましょう。

  • シフト(時間なし)
  • マスク(一定時間)
  • 加算(本質的にn²に比例する時間のように見えます)

しかし、よく見てみると、2つのトリックを使用して追加を最適化できることがわかります(さらに最適化がありますが、これらは最も重要です)。

  1. 番号を順番にではなくグループで追加できます。
  2. 最後のステップまで、2を加算して1を生成するのではなく、3を加算して2を生成できます。 2つの数値を加算して1を生成するにはnに比例する時間がかかりますが、キャリーチェーンを排除できるため、3つの数値を加算して2を生成すると一定の時間で実行できます。

したがって、アルゴリズムは次のようになります

  • シフト(時間なし)
  • マスク(一定時間)
  • 3つのグループに数値を追加して、残りが2つになるまで2つを生成します(時間はlog(n)に比例します)。
  • 最後の加算を実行します(時間はnに比例します)

言い換えれば、nにほぼ比例する時間(およびn²にほぼ比例する空間)で2つのnビット数の乗数を構築できます。 CPU設計者が専用の論理乗算を行う限り、加算とほぼ同じ速さで乗算を実行できます。


長除算では、次の入力に使用する入力を決定する前に、各減算がオーバーフローしたかどうかを知る必要があります。そのため、長い乗算の場合と同じパラライゼーショントリックを適用することはできません。

基本的な長除算よりも速い除算方法がありますが、それでも乗算よりも低速です。

6
plugwash