2012-06-19 4 views
5

構造体の各メンバの型は、通常、デフォルトの整列を持っています。つまり、構造体メンバは、あらかじめ決められた境界に整列しています。なぜデータ構造のアライメントを優先しますか?

struct MixedData 
{ 
    char Data1; 
    short Data2; 
    int Data3; 
    char Data4; 
}; 



struct MixedData /* After compilation in 32-bit x86 machine */ 
{ 
    char Data1; /* 1 byte */ 
    /* 1 byte for the following 'short' to be aligned on a 2 byte boundary 
assuming that the address where structure begins is an even number */ 
    char Padding1[1]; 
    short Data2; /* 2 bytes */ 
    int Data3; /* 4 bytes - largest structure member */ 
    char Data4; /* 1 byte */ 
    char Padding2[3]; /* 3 bytes to make total size of the structure 12 bytes */ 
}; 

アライメントが保存されるべきこと(実用的な)理由は何ですか:パディングは以下のwikiの例で行われる。このため ?

+0

[なぜC++は構造をより緊密にしていませんか?](http://stackoverflow.com/questions/6730664/why-doesnt-c-make-the-structure-tighter) –

+2

このリンクを参照してください。アライメントがどのように高速アクセスを可能にするかを理解するのに役立ちます。 http://www.geeksforgeeks.org/archives/9705 –

答えて

8

通常、アラインされていない読み取りと書き込みでは、CPUがメモリから2つの隣接ワードを(1つではなく)フェッチし、指定された演算を適切に実行するためにビット演算を追加する必要があります。

x86のようなアーキテクチャによっては、パフォーマンス上の問題が発生します。他のアーキテクチャー(特にARM)は、例外を発生させるか(通常はユーザープロセスのためにSIGBUSシグナルを出力する)、またはアドレスを最も近い境界に "丸め"て、非常に厄介なバグを招く可能性があります。

+2

さらに、並行プログラミングにとって重要なのは、整列していないアクセスをアトミックにすることはできません。 –

9

多くのアーキテクチャでは、メインメモリとのアライメントと書き込みは、アライメントされていないものよりはるかに高速です。

+9

一部では、アラインされていないアクセスは禁止されています。 – osgx

+4

一部のアーキテクチャでは、コンパイラがアライメントのない読み取り/書き込みを回避するコードを生成しない場合でも例外が発生します – mensi

+2

ほとんどのアーキテクチャでは、2ページにわたるアクセスによりMMU例外が発生し、そのようなケースを処理するオペレーティングシステムサービス。アラインメントの保証されていないコンパイラは、多くのプログラマの努力なしにカーネルを生成できませんでした。 – Potatoswatter

2

通常、構造体はプロセッサ固有のアラインメントサイズを使用して、できるだけ早くそれらにアクセスするために、プロセッサに依存するアラインメントに整列されます。

32ビットプロセッサの場合は4バイト(または32ビット)、64ビットプロセッサの場合は8バイトです。

一部の(非x86)プロセッサは、正しい境界に揃えられていない場合にintにアクセスしようとすると、フォールトを生成します。

異なるデバイス間の通信は、アラインメントを維持する実用的な理由です。デフォルトのアラインメントでは、この構造体は24バイトの長さになりますが、64ビットのプロセッサーでは48バイトとなり、最初のものを除くすべての項目は同じ場所にありません。

通常、コンパイラ/プラグマディレクティブで構造体のパディングを変更することができます。これは、例で指定した手動パディングの必要性を否定する可能性がありますが、通常はコンパイラごとに異なります。

関連する問題