1

例を挙げると、128 ビット命令を読み取る x86_64 CPU。

私が理解していることから、これは確かに x86 プロセッサで起こることです。そうしないと、たとえば、64 ビットの数値を 64 ビットのレジスタに追加することができなくなります (64 を超える数値の場合、オペコードは数ビット + 64 ビットかかります)。

私が知りたいのは、命令のビット数の制限と、ビット数 (データバス) よりも大きい場合の命令の読み取り方法です。また、ほとんどの RISC CPU が固定サイズの命令を使用していることも知っています。したがって、数値オペランドを直接渡すと、命令のサイズは単純に 2 倍になりますか?

4

2 に答える 2

6

128 ビット命令を読み取る x86_64 CPU

それは起こりません。最大命令サイズは 15 バイトに定義されています。より長い命令を作成することもできますが、それらは無効になります。

64 ビットの即値オペランドを取る命令に 16 バイトは必要ありません。そもそもそれを行う x64 命令はほんの数個しかありません。たとえば、10 バイトmov r64, imm64としてエンコードされているためです。REX.W B8+r io即値を取るほとんどすべての 64 ビット x64 命令は、符号拡張された短い即値、8 ビットまたは 32 ビットを使用します。

RISC ISA では、通常、ワード サイズと同じ大きさの即値を持つことは不可能です。2 つのステップでレジスタに大きな値を構築するか、メモリからロードする必要があります。しかし、x86 のルーツと同様に、x64 は明らかに RISC ではありません。

この質問は、(部分的に) データバスを介して 1 つずつ送られる命令の精神的なイメージによって動機付けられていると思われます。これは MIPS などには適していますが、x86 のようにアライメント要件のない可変長命令を使用すると、それをしないでください - どのような種類のブロックを選んだとしても、それは何らかの命令を通り抜けている可能性があります (そしてそうである可能性があります)。したがって、デコードは、最も単純なビューでは、バッファを備えたステート マシンであり、最初の命令をデコードしてバッファから削除し、空きがある場合はさらにバイトを埋めます (もちろん、現在はより複雑です)。

于 2016-10-10T09:42:51.840 に答える
4

ところで、命令に直接埋め込まれたオペランドデータは「即時」データと呼ばれます。


これは最新の CPU の動作ではありませんが、データ バスが最長の命令よりも狭いことは実際には問題ではありません。

たとえば、8086 は、その影響を隠すための L1 キャッシュなしで、16 ビット データ バスよりも広い命令エンコーディングを処理する必要がありました。

私が理解しているように、8086 は、デコーダーが命令全体を一度に確認するまで、ワード (16 ビット) をデコード バッファーに読み込み続けます。残りのバイトがある場合は、デコード バッファーの先頭に移動されます。次の insn の命令フェッチは、実際にはデコードされたばかりの命令の実行と並行して行われますが、8086 では依然としてコード フェッチが主要なボトルネックでした。

したがって、CPU には、許可されている最大の命令 (プレフィックスを除く) と同じ大きさのバッファーが必要です。これは 8086 の6 バイトであり、これは8086 のプリフェッチ バッファーのサイズとまったく同じです。

「デコーダーが命令全体を見るまで」は単純化されています。8086 はプレフィックスを個別にデコードし、それらを修飾子として「記憶」します。8086 には、後の CPU の 15 バイトの最大合計 insn 長の制限がないため、1 つの命令でプレフィックスを繰り返して 64k CS セグメントを埋めることができます)。


最新の CPU (Intel P6 や SnB ファミリなど) は、L1 I キャッシュから少なくとも 16B チャンクでコードをフェッチし、実際には複数の命令を並行してデコードします。@Harold's は、質問の残りの部分をうまくカバーしています。

最新の x86 CPU がどのように機能するかについて詳しく知るには、 Agner Fog の microarch ガイドタグ wiki からの他のリンクも参照してください。

また、David Kanter の SandyBridge の記事には、そのマイクロアーキテクチャ ファミリのフロントエンドの詳細が記載されています。
論文

于 2016-10-10T10:08:26.017 に答える