web-dev-qa-db-ja.com

古いマイクロプロセッサでの加算/減算演算よりもビット演算がわずかに高速だったのはなぜですか?

私は今日この抜粋に出くわしました:

ほとんどの古いマイクロプロセッサでは、ビット単位の演算は加算および減算演算よりもわずかに高速であり、通常は乗算および除算演算よりも大幅に高速です。最新のアーキテクチャでは、これは当てはまりません。ビット単位の演算は、一般に加算と同じ速度です(ただし、乗算よりは高速です)。

古いマイクロプロセッサでビット単位の演算が加算/減算演算よりもわずかに高速だった理由に興味があります。

レイテンシーの原因になると私が考えることができるのは、加算/減算を実装する回路がいくつかのレベルの論理ゲート(並列加算器など)に依存するのに対し、ビット演算ははるかに単純な回路実装であるということです。これが理由ですか?

算術演算とビット演算の両方が最新のプロセッサで1クロックサイクル内で実行されることは知っていますが、純粋に回路の伝搬時間について言えば、レイテンシは理論的には最新のプロセッサにまだ存在しますか?

最後に、ビット単位のシフト演算の実行について、概念的なCの質問がありました。

unsigned x = 1;
x <<= 5;

unsigned y = 0;
y += 32;

xyの両方が値32を保持する必要がありますが、xをその値にするには5別々の左シフトが必要でしたか(ビット単位のシフトはパイプを介して実装されます)?明確にするために、私は純粋にクロックサイクル数ではなく回路の動作について質問しています。

22
Vilhelm Gray

バイナリビット演算では、各出力ビットは入力の2つの対応するビットのみに依存します。加算操作では、各出力ビットは、入力の対応するビットと右側のすべてのビット(低い値に向かって)に依存します。

たとえば、01111111 + 00000001の左端のビットは1ですが、01111110 +00000001の左端のビットは0です。

最も単純な形式では、加算器は2つの下位ビットを加算し、1つの出力ビットとキャリーを生成します。次に、次の2つの最下位ビットが追加され、キャリーが追加されて、別の出力ビットと別のキャリーが生成されます。これが繰り返されます。したがって、最高の出力ビットは一連の加算の終わりにあります。古いプロセッサのように少しずつ操作を行うと、最後まで時間がかかります。

いくつかの入力ビットをより複雑な論理配置に供給することにより、これを高速化する方法がいくつかあります。しかし、もちろん、それはチップ内により多くの領域とより多くの電力を必要とします。

今日のプロセッサには、ロード、ストア、加算、乗算、浮動小数点演算など、さまざまな種類の作業を実行するためのさまざまなユニットがあります。今日の機能を考えると、追加を行う作業は他のタスクに比べて小さいため、単一のプロセッササイクル内に収まります。

おそらく理論的には、追加よりもビット単位の演算を高速に実行するプロセッサを作成できます。 (そして、少なくとも紙の上では、非同期で動作し、さまざまなユニットが独自のペースで動作するエキゾチックなプロセッサがあります。)ただし、使用中の設計では、プロセッサ内の多くのことを調整するために、定期的な固定サイクルが必要です。命令、実行ユニットへのディスパッチ、実行ユニットからレジスタへの結果の送信、その他多数。一部の実行ユニットは、ジョブを完了するために複数のサイクルを必要とします(たとえば、一部の浮動小数点ユニットは、浮動小数点の追加を行うのに約4サイクルかかります)。だからあなたはミックスを持つことができます。ただし、現在のスケールでは、サイクルタイムを短くしてビット単位の演算に適合させるが、追加はしないようにすることは、経済的ではない可能性があります。

25

足し算(通常は無料で引き算になります)の複雑な点は、厄介なキャリーの問題があることです。

したがって、単純な解はN倍になります 全加算器 ここで、NはALUのビット幅です。

これらの厄介なキャリーは、伝播の遅延が多いことを意味します。また、1回のキャリーオフで結果全体が不正確になる可能性があるため、すべてのキャリー値と、チェーン内の他のすべての全加算器が安定するまで、かなりの時間を待たなければなりません。

この特定のボトルネックを回避する方法はたくさんありますが、全加算器のチェーンほど実装が簡単でリソースが安いものはありません。 (最速はシリコンに実装されたルックアップテーブルです)

詳細が必要な場合は、おそらく http://electronics.stackexchange.com で質問する必要があります。

4
Earlz

あなたの最後の質問に答えるために、それは異なります。一部のアーキテクチャ(z80など)は1だけシフトし、一部のアーキテクチャはより大きな定数や変数によるシフトを公開しますが、実装 「1シフト」(x86の古い実装など)、1サイクルで1を超えてシフトできるアーキテクチャがいくつかありますが、シフト量が一定の場合にのみ、いくつかのアーキテクチャ(最新の実装など)があります。 バレルシフタ を使用し、単一サイクルで変数によってシフトできるx86)の場合、さらに多くの可能性があります。

バレルシフタの回路の深さは、それが実行できる最大シフトの対数です。これは必ずしもレジスタの幅ではありません。幅より1つ小さい場合もあり、さらに小さいと考えられます。

2
harold

一部の追加実装では、キャリービットに対して追加のサイクルを実行する必要があります。例:16ビット整数には、8ビットプロセッサで複数の命令が必要です。これはシフトにも当てはまります。ただし、シフトは常に高さビットを次のバイトの下位ビットにシフトできます。追加では、追加のラウンドで下位ビットを追加する必要があります。

0
Lukas