2017-08-29 6 views
0

を再生しますどのように?メモリからデータを読み込み、どのように私はCPUはキャッシュが重要な役割

Bextradata = (U8_WMC *) malloc(Size); 
memset(Bextradata, 0,Size); 
memcpy(BextraData,pdata + 18,Size); 
ように私は(もmalloc関数を使用して割り当てられている構造体のメンバーである)変数Bextradataにメモリを割り当てるのですコードの一部を書かれているに

以降、他のファイルでこの変数を読み込もうとすると、この変数はメモリからどのように読み込まれますか。この変数はキャッシュに格納されるか、メインメモリから読み込まれます。あなたはCPUの動作を理解する前に予め

+0

使用しているプロセッサ+ OSプラットフォームによって異なります。私はキャッシュを持っていないプラットフォームで作業しています。 – Vagish

+0

キャッシュを有するシステムは、キャッシュライン(例えば、一度に32または64バイト)によってメインメモリを読み取る。したがって、変数にアクセスしなくても、常にチャンスがあります。既に他のコードによって読み取られています。 –

答えて

1

おかげで、あなたはいくつかの用語を理解する必要があります。 CPUは、ALU(算術論理演算用)、制御ユニット、および多数のレジスタで構成されています。 CPU内のレジスタの数は、アーキテクチャによって異なります。存在するレジスタのタイプは、汎用レジスタ、専用レジスタ命令ポインタおよび他のいくつかのものである。あなたはそれらについて読むことができます。現在、32ビットプロセッサまたは64ビットプロセッサと一般的に言えば、CPUのレジスタのサイズを参照しています。

今すぐ次のコードを見てみましょう:上記のプログラムがロードされると

int a = 10; 
int b = 20; 
a = a + b; 

、それの命令は、メインメモリに格納されています。プログラム内のすべての命令は、メインメモリ内のある場所に格納されます。各場所は特定のサイズを持っています(アーキテクチャにもよりますが、1バイトと仮定します)。すべての場所には住所があります。 RAM内の特定の位置のアドレスのサイズは、命令ポインタのサイズに等しい。 64ビットシステムでは、命令ポインタのサイズは64ビットになります。つまり、2^64-1の位置までアドレス指定できます。 1つの場所は一般的に1バイトなので、64ビットシステムの理論上の合計RAMは16エクサバイトになる可能性があります。 (32ビットシステムの場合は2^32-1〜4 GB)

ここでは、最初の命令a = 10を見てみましょう。これはストア操作です。コンピュータは、追加、乗算、減算、除算、格納、ジャンプなどの基本的な操作を行うことができます。プロセッサの命令セットを読むことができます。再度、命令セットはシステムによって異なる。プログラムがメモリにロードされると、命令ポインタは最初のアドレスまたはベースアドレスを指し示します。この場合、a = 10です。この場所の内容は、CPUの汎用レジスタの1つに持ち込まれます。これは、これがストア演算であることを理解するALUに送られる(ストア演算としてそれを表す追加のビットが追加される)。 ALUはそれをRAM内およびキャッシュ内のいずれかの場所に格納します。キャッシュに格納するかどうかは、コンパイラとハードウェアプリフェッチと呼ばれる概念によって決まります。コンパイラがプログラムを解析するとき、頻繁に使用される変数を見て、それらをキャッシュに格納できるようにします。この場合、変数 'a'が再び使用され、コンパイラが中間命令をプログラムに追加してキャッシュにも格納するようになります。どうして?より高速にアクセスできます。

最初の命令が実行された後、命令ポインタがインクリメントされ、2番目の命令すなわちb = 20を指すようになります。同じことが起こります(速度に関しては、常にレジスタ>キャッシュ> RAM>これも同様に。

3番目はa = a + bです。これには、実際には4つの操作(アセンブリレベルを見ている場合)、つまり1)フェッチa、2)フェッチb、3)aとbを追加、4)結果をaに格納します。変数aとbはキャッシュ内に存在するので、それらはそれらの場所から持ち出されます。それらは追加され、結果はaに保存されます。

どのように動作するのかご理解いただければ幸いです。

また、プログラムがメインメモリにロードされるときに、それが特定の領域を占有することを知る必要があります。このスペースはセグメントと呼ばれます。ベースアドレスと最終アドレスを持っています。最初の命令はベースアドレス、最後の命令は最終アドレスと見なすことができます。あなたのプログラムから、このセグメントの外側から指すポインタを間接参照しようとすると、有名なエラー、Segmentation faultが発生します。例えば:私は値NULLであり、NULLがセグメントではないので、それはワンセグ障害を与えるアドレスを格納するポインタ間接参照しようとしているよう

int *ptr = NULL; 
printf(*ptr); 

は、これは私のセグメンテーションフォールトを与えるだろう。

+0

変数aとbはキャッシュに存在するので、これらの場所から変数aとbが取り出されます。それらは追加され、結果はaに戻されます.->この結果は両方の場所で更新されますか?私はRAMとキャッシュを意味します。 – prashant

+0

キャッシュプリフェッチと呼ばれる概念に依存します。コンパイラがコードをコンパイルすると、特定の変数の反復を解析します。たとえばa = a + bの命令の後に変数aを使用する命令がもう1つある場合は、それをキャッシュに格納することも論理的です。コンパイラは、コンパイル中に追加の指示を追加することで、あなたのためにそれを行います。これはソフトウェアプリフェッチと呼ばれます。 –

+0

これは概念レベルでは正しかったのですが、最も単純な最適化コンパイラでも、コードは 'int a = 30;'と同じで、どこでも 'b'を格納する必要はありません。そして、おそらく 'a'でもなく、次に起こることに依存します。 –

関連する問題