なぜあなたは、単純な解析メモリのアライメントおよび位置揃え規則が必要なのか

Ubuntuの16.04.2コンパイラー環境アームlinux3.4.5にlinux-2.6.22.6

知っている最初の必要性がある:CPUがメモリや命令ではなく、仮想1バイト取らスプライシングからデータを取り出しているが、それらの語長によれば、CPUのデータ長を処理することができ、抽出メモリブロック、例えば32ビット、32ビットプロセッサは、処理のためにメモリの4つのバイトブロックを取り出します。どのように行うために2バイトのみである:ここで質問がありますか?答えは削除されるか、4つのバイトは、その後、プロセッサメモリは、CPUへのピックでのデータ転送を完了するのに役立ちます。

要するに、CPUはなり「最も快適」また別の問題につながるメモリデータを、読むためにデータ長:

4バイト長の命令があればCPUに読み込まれる準備ができている、2例があります発生します。

    ちょうどCPUによってリードアドレスのアドレスを開始1,4バイトは、このケースでは、1は、CPUの命令を置くことができ、メモリは次のように、読み出し、および実行

     4つのバイトは、次の分布に応じて、図2に示すように、。

   

 

得られた1,2バイトの最初のクワドレットデータをフェッチするために、同じCPUアドレスからデータをフェッチも仮定が、データが必要数を満たしていない、ああ、CPUは、後続のメモリに続けます値は、これが4バイト単位の後ろに取られ、前面に到達するためにデータの3、4バイト由来、および完全な2バイトのデータに組み立て、この二つのメモリは、読み出し動作最初のダイレクトアウトと比較して、より一回の操作よりも、ざっと見は1つのより少し影響のようですが、データおよびコンピューティングの操作の多くを行うためのCPUを考慮し、これは多くのことを起これば、それから、無視できないCPUを行います「余分なアクション」の量は、真剣に、処理速度に影響を与えます。

 

したがって、システムは、それによってCPUの処理速度を増加させる、メモリアライメントを行う必要があり、この作業は、適切なアドレス割り当てと最適化を行うためにコンパイラに与えられ、コンパイラは、対応するメモリ位置合わせパラメータまたはターゲット環境に応じて提供されます。(もちろん、整列メモリのハードウェア面の理由があり、ハードウェアの一部が所定のアドレスを読み取るために、命令アドレスは、アドレスが一致しない場合、状況は不明であるようにその規定は、ハードウェアがクラッシュすることがあります)

 

メモリアライメントに分割され、自然配向および正規アラインメント

自然なアラインメントは、対応するメモリ空間にアドレス値に対応する変数の型を指す、すなわち、そのデータ・タイプのアドレスに格納されるデータは、その種類に応じてデータの倍数です。例えば、1バイトの文字スペースを入力し、すべての数が1の倍数であり、任意のアドレスに配置させることができ、INT 4は0,4,8のように持っているのアドレス複数に4バイトの空間であります。コンパイラは、アドレスの割り当てに基づいて優先的に自然なアライメントデータになります。

 

天然の配列に配向させた例ルールの構造では、コンパイラは、自然配向ボイドが無効なデータメモリを充填し、充填後の構造が最大整数データメモリ空間の可変型部材を表す構造内のメモリ空間を占有生成します回。次に、上述した位置合わせ規則について説明します。

(注:特別な命令が指定された環境コンパイラGCCを使用して、32ビット環境ではない-m32)

まず、次のテストコードされています

#include <stdio.h>
int main(int argc,char** argv)
{
    printf("%d",sizeof(struct name));
    return 0;
}

出力は、メモリ空間が構造を占領しています。

 

 

1.まず、このような構造を見て

typedef struct test_32
{
	char a;
	short b;
	short c;
	char d;
}test_32;

まず、天然のアラインメントに従って、(同じ試験後、バックインクリメントされる第1グリッドアドレス0)プロファイルメモリ以下位置を取得します

 

コンパイラの規則に従って、無効なデータの空白を埋めるだろう整列し、最後にこれだけのメモリ空間の結果として得られる構造は8バイトで、この値のデータの2バイト型ショートの最大の整数倍である、プログラムがコンパイルされます得られた結果は、8バイトです。

 

 

2.構造の位置の少しの変化を見てみると

typedef struct test_32
{
	char a;
	char b;
	short c;
	short d;
}test_32;

また、以下の自然配向の分布に従います。

 

規則が整列を充填する必要はないが、ここでの規則に従って整列6バイトで6色の正方形が存在するので、自然なアラインメントで見ることができ、隙間は、変数間の発生しない、この構成は6バイトであります最大データ本体型ショートの整数倍なので、この構造は6バイトであり、後者のブランク及びそれを無視するが、実際にコンパイルすることができます。それが実行され、6バイトの分析の結果と一致します。

 

 

特定の状況を知っている二つの例は、実質的に整列させることができる上に、メモリから、ケースを追加する必要があるが、ケースは二重であり、我々は32ビットのプロセッサのみを扱うことができることを知っている32 4バイトのデータであり、二重それに対処する方法である8バイトのデータ型、?処理は4バイトの数を倍増するために2つに分割されるが、64ビットプロセッサ場合、データの最初の8つのバイトは、double8バイトのデータを扱うことができるように、処理され、32ビットプロセッサにすることができます次のような状況になりますここでは、処理します:

typedef struct test_32
{
	char a;
	char b;
	double c;
}test_32;  

この構造は、32ビットのメモリ空間にある12のバイトによって占有されている、64ビット環境共有メモリ空間内に16バイトであるが、上述した理由は、二つにのみ下位32ビット分割、異なる処理モードによるものです4バイトの処理なので、構造の最大アライメントルールデータ型は4バイトであるが決定する、全体の長さ、すなわち12バイト、4バイトの整数倍です。64は、8バイトの最大値を決定し、その結果は、8バイトの整数倍である:16バイト。ここでは構造がアドレス理論で8バイトの倍数に自然な二重の整列に配置されていない、私はルールが整列に応じて追加の4バイトを保存し、最適化コンパイラもあると考えています。この部分は、彼らは、上記のルールに従って、独自の分析をテストすることができます。

 

(注:以下のハードウェア関連の内容とメモリの内容を有する比較的大きな、整列関係は大きくない、見ることができません)

さらに、C言語のアラインメントを拡大下では適用可能であるが、コンパイルのため、制御アドレスへのユーザの編集より透明ように、基本的に任意で呼び出すことができ、これだけできるだけ揃えることができ、一般的には、正常であろう整列、私はの使用と同様アセンブリコードでテストを行うためのprintf関数を呼び出すARMアーキテクチャでアセンブリで記述された起動コードを、遭遇したとき、

.ascii  "Hello ARM!\0"

実施形態では、文字列を定義し、参照番号の前に配置され、パラメータとしてprintf関数を渡すために、このコマンドの後私のBLメインジャンプ命令の主な機能であります

これは、実際のテストシステムクラッシュことが判明し、出力が正常であると述べました。解体文字列があるとしてDAMAアドレスの割り当て、後続の命令につながるが揃っていないことが判明した後、

メモリは4の倍数でないときに注意してください、この場合は、問題を解決するだろう後の前で.ALIGN 4 ALIGNディレクティブを追加します知っています。

だから、いくつかのハードウェアやメモリの位置合わせのために、それは非常に重要です。

また、学習保つために近い完璧な結論に、プログラムの作成の基礎となる考え方、最適化され、書き込みコードのこれらの側面を考慮しなければならないも自分自身を思い出させる - ???

 

 

為替へようこそ、議論したり私を修正!一般的な進歩!

公開された19元の記事 ウォン称賛7 ビュー6938

おすすめ

転載: blog.csdn.net/G_METHOD/article/details/79535178