6

構造体の各メンバーのタイプには通常、デフォルトの配置があります。つまり、各構造体メンバーは事前に決定された境界に配置されます。このため、次のwikiの例ではパディングが実行されます。

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 */
};

アラインメントを維持する必要がある(実用的な)理由は何ですか?

4

3 に答える 3

9

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

于 2012-06-19T10:55:08.777 に答える
9

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

x86などの一部のアーキテクチャでは、パフォーマンスを犠牲にしてそれを許可します。他のアーキテクチャ(特にARM)は、例外を発生させるか(通常SIGBUS、ユーザープロセスのシグナルを生成します)、アドレスを最も近い境界に「丸め」て、非常に厄介なバグを発生させる可能性があります。

于 2012-06-19T11:00:59.197 に答える
2

通常、構造体は、プロセッサの「自然な」レジスタサイズを使用して可能な限り迅速にアクセスできるように、プロセッサに依存する配置で配置されます。

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

一部の(x86以外の)プロセッサは、intにアクセスしようとすると(たとえば)、正しい境界に整列されていない場合に障害を生成します。

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

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

于 2012-06-19T11:01:53.797 に答える