プロセッサが32個のレジスタで停止した理由を常に疑問に思っていました。それはマシンの群を抜いて最速のピースです。より多くのレジスタを備えたより大きなプロセッサを作ってみませんか?それは、RAMへのアクセスが減ることを意味しませんか?
プロセッサが32個のレジスタで停止した理由を常に疑問に思っていました。それはマシンの群を抜いて最速のピースです。より多くのレジスタを備えたより大きなプロセッサを作ってみませんか?それは、RAMへのアクセスが減ることを意味しませんか?
回答:
まず、すべてのプロセッサアーキテクチャが32レジスタで停止したわけではありません。命令セットで32個のレジスタが公開されているほとんどすべてのRISCアーキテクチャには、実際には32個の整数レジスタと32個の浮動小数点レジスタがあります(つまり64個)。(浮動小数点「add」は整数「add」とは異なるレジスタを使用します。)SPARCアーキテクチャにはレジスタウィンドウがあります。SPARCでは、一度に32個の整数レジスタにしかアクセスできませんが、レジスタはスタックのように動作し、一度に16個の新しいレジスタをプッシュおよびポップできます。HP / IntelのItaniumアーキテクチャには、128個の整数レジスタと128個の浮動小数点レジスタが命令セットで公開されていました。NVidia、AMD、Intel、ARM、およびImagination Technologiesの最新のGPUはすべて、レジスタファイル内の膨大な数のレジスタを公開しています。(私はこれがNVidiaおよびIntelアーキテクチャに当てはまることを知っています。AMD、ARM、およびImaginationの命令セットにはあまり精通していませんが、レジスタファイルも大きいと思います。)
第二に、ほとんどの最新のマイクロプロセッサは、レジスタの名前変更を実装して、リソースを再利用する必要があることによる不必要なシリアル化を排除します。そのため、基礎となる物理レジスタファイルは大きくなりますコンパイラが非常に多くの一意のレジスタ名を生成すると同時に、スケジューラに大きなレジスタファイルを提供する必要がある。
命令セットで公開されるレジスタの数をさらに増やすのが難しい場合がある理由は2つあります。まず、各命令でレジスタ識別子を指定できる必要があります。32レジスタには5ビットのレジスタ指定子が必要なため、3アドレス命令(RISCアーキテクチャでは一般的)は、レジスタを指定するためだけに32命令ビットのうち15ビットを使用します。これを6ビットまたは7ビットに増やした場合、オペコードと定数を指定するスペースが少なくなります。GPUとItaniumには、はるかに大きな命令があります。大きな命令にはコストがかかります。より多くの命令メモリを使用する必要があるため、命令キャッシュの動作は理想的ではありません。
2番目の理由はアクセス時間です。メモリを大きくすると、メモリからのデータへのアクセスが遅くなります。(基本的な物理学の観点から言えば、データは2次元空間に格納されるため、ビットを格納する場合、特定のビットまでの平均距離はです。)レジスタファイルは単なる小さなマルチポートメモリ、およびそれを大きくするための制約の1つは、最終的には、より大きなレジスタファイルに対応するために、マシンのクロックを遅くする必要があることです。通常、全体的なパフォーマンスの観点では、これは損失です。 O (√
レジスタの数を制限するもう2つの理由:
多くのコードには多くのメモリアクセスがあります(30%は典型的な数値です)。このうち、通常は約3分の2が読み取りアクセスで、1/3が書き込みアクセスです。これは、配列へのアクセス、オブジェクトメンバー変数へのアクセスなど、レジスタが不足しているためではありません。
これは、C / C ++の作成方法が原因で、メモリ(またはデータキャッシュ)で実行する必要があります(ポインタを取得できるものはすべて、潜在的にメモリに格納する必要があるアドレスを持つ必要があります)。コンパイラが、狂った間接ポインタトリックを使用して意外に変数に書き込みを行わないと推測できる場合、それらをレジスタに配置します。これは、関数変数に対してはうまく機能しますが、グローバルにアクセス可能な変数(一般的には、malloc ())グローバル状態がどのように変化するかを推測することは本質的に不可能だからです。
このため、コンパイラがとにかく16個以上の汎用レジスタを使用して何でもできるようになることは一般的ではありません。すべての人気のある建築家がその数について持っている理由です(ARMには16があります)。
MIPSや他のRISCには32があります。これは、それほど多くのレジスタを用意するのがそれほど難しくないためです-コストが十分に低いので、「なぜ?」32以上はほとんど役に立たず、レジスタファイルのアクセスが長くなるという欠点があります(レジスタの数を2倍にするごとに、マルチプレクサの層が追加され、遅延が少し増える可能性があります...)。また、平均して命令がわずかに長くなります。つまり、命令メモリの帯域幅に依存する種類のプログラムを実行すると、余分なレジスタが実際に速度を低下させます。
CPUの順序が正しくなく、レジスタ名の変更を行わず、サイクルごとに多くの操作(3つ以上)を実行しようとしている場合、理論的には、サイクルごとの操作数が増えるにつれて、より多くのレジスタが必要になります。これが、Itaniumに非常に多くのレジスタがある理由です!しかし、実際には、数値浮動小数点またはSIMD指向のコード(Itaniumが得意)を除き、ほとんどのコードには多くのメモリ読み取り/書き込みとジャンプがあり、サイクルあたり3を超える操作というこの夢を実現できません。 (特に、データベース、コンパイラ、javascriptなどの高レベル言語実行、エミュレーションなどのようなサーバー指向ソフトウェアで)。これがItaniumを沈めたものです。
すべては、計算と実行の違いに帰着します!
プロセッサに常に 32個のレジスタがあることを誰が教えてくれますか?x86には8個、ARM 32ビット、x86_64には16個、IA-64には128個、その他多くの数字があります。あなたは見ることができ、ここで。MIPS、PPC、または命令セットに32個の汎用レジスターがあるアーキテクチャーでも、フラグレジスター(存在する場合)、制御レジスター、名前変更されたレジスターおよびハードウェアレジスターは含まれないため、その数は32よりもはるかに大きくなります。
すべてに価格があります。レジスタの数が多いほど、タスクの切り替え時に多くの作業が必要になり、命令のエンコードに必要なスペースが増えます。レジスタが少ない場合、関数を呼び出したり、関数から戻ったり、タスクを切り替えたりするときに、一部の計算量の多いコードにレジスタがないというトレードオフを考慮して、保存や復元を行う必要はありません。
さらに、レジスタファイルが大きいほど、高価で複雑になります。SRAMは最速で最も高価なRAMなので、CPUキャッシュでのみ使用されます。ただし、同じ容量のレジスタファイルよりもはるかに安価であり、面積も小さくなります。
たとえば、典型的なIntelプロセッサには、「公式に」16個の整数レジスタと16個のベクトルレジスタがあります。しかし、実際にはさらに多くのことがあります。プロセッサは「レジスタ名の変更」を使用します。命令reg3 = reg1 + reg2がある場合、reg3を使用する別の命令がまだ終了していないと問題が発生します。前の命令によって読み取られる前にreg3を上書きする場合、新しい命令を実行できませんでした。
したがって、約160ほどの実際のレジスタがあります。したがって、上記の単純な命令は「regX = reg1 + reg2に変更され、regXにはreg3が含まれていることを覚えておいてください」。レジスタの名前を変更しないと、順不同の実行は完全に死んでしまいます。
私は電気技師ではありませんが、レジスタの数を制限する理由の別の可能性はルーティングです。演算ユニットの数には限りがあり、すべてのレジスタから入力を取得し、すべてのレジスタに出力できる必要があります。これは、サイクルごとに多くの命令を実行できるパイプラインプログラムがある場合に特に当てはまります。
これの単純なバージョンは、複雑さを持ち、レジスタの数をスケーラブルにできないようにします。
この答えは、Ivan GodardのMill CPUに関する講演を見ることで得られました。Mill CPUの革新の一部は、任意のレジスタに出力できないことです。出力はすべてレジスタスタックまたは「ベルト」にプッシュされるため、出力の行き先が常にわかるため、ルーティングの問題が軽減されます。入力レジスタを演算ユニットに送るためのルーティングの問題がまだ残っていることに注意してください。
参照してくださいベルト(9の2) -ミルCPUアーキテクチャを、問題文の、そしてミルのソリューション。