3

変数がabooleanまたはa char(C / C ++の場合)またはbyte(Javaのような言語の場合-VM上でJavaを待つ必要はありません)、CPUが1バイトより大きい単語を使用する場合、スペースは無駄になりませんか?変数をメモリに格納すると、ワードが4バイトであっても、たとえば1バイトなどよりコンパクトに格納できると聞きました。誰かがこれがどのように起こるかを説明できますか?レジスタはRAMよりもプレミアムであるため、逆に見えます。

4

7 に答える 7

8

数値を格納する機能にもかかわらず、レジスタは正確に「スペース」ではありません。

この例を考えてみましょう。大きな箱の中にたくさんの名刺があり、それらをアルファベット順に並べたいと考えています。その過程で、ボックス内のカードをある場所から別の場所に移動します。カードをボックス内の新しい場所に移動する間、カードを手に持っていますが、ボックスと同じ意味で、カードを手に保管することはできません。あなたの手の中にある場所は、「スペース」と呼ぶにはあまりにも価値があります。

カードの例えを続けて、カードのサイズが異なると想像してください。手の大きさで、一度に1枚の大きなカード、2枚の中型のカード、または4枚の小さなカードを保持できます。ただし、カードを並べ替える場合、特にカードが均一にシャッフルされている場合は、複数のカードを取得できることはほとんどメリットがありません。複数のカードには複数の宛先スポットがあるため、つかむ場合は、より複雑または不要な操作を行う必要があります。同時に複数のカード。

同様に、CPUのレジスタには複数のバイトが含まれる場合がありますが、計算を実行する必要がある場合、使用するバイトをCPUに指示する方法がないことがよくあります。レジスタは分割できない単位として操作に参加します。そのため、1バイトだけで十分ですが、レジスタ内のデータにはワード全体が使用されます。

于 2012-07-16T21:29:20.073 に答える
6

一般的に言えば、ワードは単一のレジスタに収まるデータの量です。

レジスターをたとえば8ビットのように狭くした場合、2つの32ビットintを追加するのに複数のサイクルが必要になります。

また、RAMアドレス空間も単語の中に収めたいと思います。

于 2012-07-16T21:10:51.210 に答える
2

各命令セットには、これらの種類の定義があります。たとえば、1バイトは8ビットまたは9ビットまたはその他のサイズです。単語は、そのアーキテクチャによって何かを意味するように定義されています。

8086/8088は、バイトを8ビット、ワードを16ビットと定義しました。16ビットレジスタがありましたが、8ビットハーフレジスタとして使用することもできます。axは16ビットレジスタです。ahはaxの上半分で、alは下半分です。典型的ではありませんが、彼らがそれをどのように行ったか。その後、80x86 EAXは32ビットレジスタになり、そのaxは下半分になります。ワードは16ビットとして定義されているため、EAXはダブルワードまたはdwordとして定義されます。その後、64ビットレジスタが登場しました...このアーキテクチャでは64ビットはクアッドワードと呼ばれています。

ARMは、バイトを8ビット、ハーフワードを16ビット、ワードを32ビットと定義しています。他の人もこれを行います。

それはハードウェアレベルです。次に、プログラミング言語に入ると、定義を自由に変更できます。また、typedefなどを利用して他の定義を作成または変更したいプログラマーも、自由に任意のサイズを作成できます。言語サイズはハードウェアと一致する必要はありません。一致するのは良い考えですが、一致する必要はありません。特定のターゲットのコンパイラやバックエンドを実装するのは誰でもかまいません。

廃棄物について...

x86アーキテクチャは、可変ワード長の命令を使用します。つまり、8ビット命令、16ビット命令、24ビット、32ビットなどがあります。あるレジスタから別のレジスタに移動したい場合、その命令は1バイトしかかからないかもしれませんが、16ビット値をレジスタに移動したい場合、それは1バイトかかるかもしれません。 、次にさらに2バイトを定義して、その命令の即時の合計3バイトを定義します。命令セットは、メモリが8ビット幅のときに発明されました。8ビット幅のメモリシステムの場合、これは理にかなっています。32ビットと64ビット幅のメモリシステムを使用しているので、これは非常に苦痛です。それにもかかわらず、命令セットには8ビットレジスタ、ah、al、bh、blなどがあり、8ビットレジスタに対して8ビット演算を実行できます。したがって、スペースを節約するために、ブール値などを1バイトのサイズにするのが理にかなっている場合があります。とにかく、アライメントなしでメモリを可変サイズに切り刻んでいるのかもしれません。

ARMは、従来のARM(thumb / thumb2ではない)を考えると、命令は常に32ビット幅であり、それ以上でもそれ以下でもありません。x86ビットよりも多くのレジスタがあり、ハーフレジスタまたはバイトサイズのレジスタに分割されていません。比較などの8ビット演算はありません。レジスタごとに行われるため、すべてが32ビットです(いくつかの小さなイミディエートがあります、はい)。高水準言語の変数が-5未満または+20を超えることは決してない場合は、高水準言語の符号付きバイトを使用してスペースを節約することをお勧めします。32ビットレジスタを使用して8ビット演算をシミュレートするには、データを符号拡張またはマスクするために追加の命令を使用する必要がある場合があります。3バイトを節約すると、4または8以上のコストがかかります。32ビット整数は符号付きバイトよりも安価でした。

x86が非アラインメントアクセス(たとえば、32ビットデータバスを使用したアドレス0x4からの32ビット読み取り/書き込み)を許可するという理由だけで、アラインメントの問題があり、余分なサイクルがかかります。ARMなどはこれを許可していません。しかし、同じように、キャッシュを介した場合でも、キャッシュは32ビット幅のRAMである可能性が高いため、バイト書き込みには読み取り-変更-書き込みのコストがかかります。1バイトを変更するには、32ビットを読み取り、8を変更し、32を書き戻す必要があります。クロックサイクルのコスト。8ビット変数の代わりに32ビット変数を使用した場合、その変数が-5から+20の範囲外になることはありません。あなたはあなた自身により多くのクロックサイクルを要します。より多くの無駄。

ここで、8ビットレジスタを備えたシステムが32ビットシステムよりも32ビット数を追加するのに多くのサイクルを要する理由についての質問についてです。あなたはおそらく小学校に通い、鉛筆と紙で追加することを学んだので、これに対する答えをすでに知っています。

3桁のレジスタが許可されている世界で10進数123+789を加算したい場合は、その加算を1サイクルで実行できます。

 110 <--- carry bits/numbers
 123
+789
====
 912

これを32ビットレジスタベースのシステムと考えてください。現在、8ビットレジスタベースのシステムでは、世界は一度に1桁しか許可していません。

キャリーインが0の1サイクル3+9

 10 
  3
+ 9
====
  2

キャリーアウトは1であり、キャリーインを取得するためにその操作を実行する必要があります。これにより、次のレジスタセットを使用した次の操作、キャリーイン1を使用した次のサイクル2+8のキャリーインとして使用できます。

 11 
  2
+ 8
====
  1

キャリーインも1、3番目のサイクル1 + 7で、キャリーインは1です。

 01
  1
+ 7
====
  9

必要に応じて実行は0です...

記数法は関係ありません(基数10、基数2など)。すべて同じように機能します。

たとえば、2と3があり、それらを足し合わせたい場合、64ビットプロセッサで2つの64ビットレジスタを使用して次のような操作を実行するのは非常に無駄に思えます。ほんの数ビットの列を取ります。同様に、メモリなどとの間でそれらを保存します。ブール演算またはalu演算(add、orなど)の場合、レジスタの幅は、パイプラインの平均が1クロックで、その幅に合わせて設計されているかどうかは関係ありません。何があっても64ビットの追加を実行します。はい、それは多くの無駄なロジック不動産です。上記を参照してください。使用するロジックを少なくするか、クロックを増やすか、ロジックを増やしてクロックを少なくするかを選択できます。より多くのクロックソリューションには、より多くのメモリサイクルが含まれる可能性があり、さらに多くのクロックが必要になります。より広い変数はより多くのRAMを浪費するかもしれませんが、より広いメモリシステムでより少ないクロックを使用します。それはすべてトレードオフです。現在、ロジックは数ギガヘルツで最大になり、メモリは非常に遅くなりますが、バスを広くしたり、他の並列トリックを使用したりすることで、バスをより速く表示できます。クロックサイクルを犠牲にしてロジックとRAMにそのお金を節約した場合、リアルタイムで、または何が起こっているのかを確認するのに十分なピクセルでYouTubeビデオを見ることができない可能性があります。または、数学関数を使用して圧縮されることが多いフォントや画像の描画には、ユーザーが耐えられないほど長い時間がかかるため、Webを閲覧します。

microchippic命令セットをご覧になることをお勧めします

http://en.wikipedia.org/wiki/Microchip_PIC

上記のページにリストされている12ビットの命令セットテーブル。最後に作成したプログラムについて考え、その命令セットを使用してそのプログラムを実装します。さらに良いことに、pic命令セットを使用して3つの単純な数値を追加します。レジスタは1つだけです。数学を行うには、1つのオペランドを取得してwレジスタに入れ、fレジスタを使用して数学を実行する必要があります。たとえば、fレジスタの内容を台無しにしたくない場合は、そのままにします。結果はwレジスタになります。次に、別のfレジスタ、結果をwに追加し、次に3番目のレジスタ、結果をwに追加し、wを4番目のfレジスタに保存します。d = a + b+c。確かに、アームやミップなど、その1つの操作にa、b、cだけが必要な場合は、3回の読み取りを実行してから追加する必要がありますが、これらのオペランドの1つ以上が他の操作の結果である場合は より多くのレジスターなどがあるため、RAMに保管する必要はありませんでした。規模の経済が見られるようになります。6502(ゼロページを理解していない限り表面上)および他の命令セットは、クロックサイクルを犠牲にして、より少ないロジック、より少ないRAMを対象としていました。古い設計(x86を含む)の場合、これはロジックの作成と構築に(比較的)費用がかかり、メモリも同様に費用がかかるためでした。

プロセッサのこの単純化は、クロックサイクルを極端に犠牲にして、1つの命令にすることができます。

http://en.wikipedia.org/wiki/Single_instruction_set_computer

opencores.orgには、これらの1つまたはいくつかの命令プロセッサがいくつかあります。

Javaについておっしゃいましたが、その仮想マシンは、ハードウェアで構築する場合、クロックサイクルを犠牲にして(移植性の見返りとして)動作します。スタックベースのプロセッサの例については、opencoresのzpuを参照してください(Javaではなく、スタックベースのソリューションの別の例です)。確かにJavaで発明されたわけではなく、pascalは元々スタックベースの擬似コードでしたが、その擬似コードをターゲットに実装しました。各ターゲットに実装したsmall-cで生成されたスタックベースのプログラムなど。スタックベースのソリューションは、クロックサイクルを犠牲にして非常に移植性があります。

あなたの質問に対する簡単な答えは、マイクロにあまり焦点を当てないで、少し後ろに立って全体像を見るということです。プロセッサでますます大きなレジスタを使用する理由は、速度のためです。ほとんどの場合、64ビットプロセッサのalu演算でこれらのアドレスビットまたはデータビットのすべてを使用しているわけではありませんが、そうです、それらのより広いレジスター、それらのより広いバス、そしてメモリーは、他の場所での無駄を補うのに十分な、大きなパフォーマンスの違いを生み出します。とにかく無駄はかなり安いです、プロセッサ、メモリ、ディスクスペース、8ビットマルチギガヘルツシステムのコストは、同じユーザーエクスペリエンスを提供する必要がある場合、またはそれに十分近い必要がある場合、64ビットマルチギガヘルツシステムよりも8倍安くはありません同じ。

于 2012-07-17T05:49:28.730 に答える
1

バス幅に関係します。プロセッサの各クロックサイクルは、バス幅に関してプロセッサ全体を前方に移動させるため、オペランドタイプごとにレジスタ幅を最適化することはおそらく不可能です。

于 2012-07-16T21:12:32.503 に答える
0

アーキテクチャのstore-byte命令(通常はレジスタの下位ビットをメモリ位置に格納します)を使用して、ワードサイズのレジスタから1バイトの値をメモリに格納できます。

于 2012-07-16T21:24:36.547 に答える
0

初期のコンピュータの多くは、データを少しずつ、通常は4ビットまたは6ビットの数字で保存していました。これは、データパスが狭く、演算が一度に1桁ずつ連続して行われる場合に、かなりうまく機能しました。そして、それは保管において効率的でした(これは貴重な商品でした)。

ストレージはもはやそれほど貴重ではありません-スループットは-そしてコンピュータはより広いデータパスでより良いスループットを達成することができます。

于 2012-07-16T22:07:12.163 に答える
0

考えるべきことの1つ:

プロセッサ設計のための「最新の」(1985年頃)RISCスキームは、プロセッサチップにかなり多くのかなり広いレジスタを配置する方が、の「コスト」(チップの「不動産」)と比較して比較的安価であることを考慮に入れています。 「制御ロジック」。

この議論の完全な真実を疑う理由はありますが、いくつかの真実の要素があり、レジスタは同じ量のRAMよりも何倍も(おそらく1000以上)高価ですが、それでも比較的安価です。レジスターを狭くし、同じ操作を実行するためにより多くのサイクルを必要とするのは誤った経済です。代わりに、設計者は1つのサイクルで可能な限り多くのことを達成しようとします。

于 2012-07-17T00:53:39.837 に答える