2

SOで整列属性に関して非常に多くの質問が寄せられているのを見てきましたが、どこで利点を見つけたのか、いつこれを使用するのかはわかりません(つまり、正確にどこで、どのシナリオでこの概念を使用する必要があるかを意味します)。それの写真。SO の質問 1 つのプログラムから 1 つのプログラムをコピーして、整列された属性参照用に 1 つのプログラムをコピーしただけです

int main( )
{
    構造体データ
    {
        int a __attribute__( ( 整列 ( 8 ) ) ) ;
        char ch __attribute__( ( 整列 ( 1 ) ) ) ;
        float s __attribute__( ( 整列 ( 4 ) ) ) ;    
    };
    構造体データ e ;
    printf ( "\n%u %u %u", &e.a, &e.ch, &e.s ) ;
    printf ( "\n%d", sizeof ( e ) ) ;
    0 を返します。
}
4

2 に答える 2

1

アラインメントの重要性は、主にパフォーマンスと移植性を表しています。使用しているプラ​​ットフォームのアライメント要件を理解していない場合、コードをそこで実行できるとは限らないか、誰かがそのプラットフォームに適切にアライメントされていないコード(またはデータ)を移動するとすぐに壊れてしまう可能性があります。

ハードウェアやOSなどに応じて、これの一部は自動的に処理されますが、アライメントルールを破るとペナルティが発生します。デフォルトでは、古いバージョンのWindowsは、アライメント障害が発生した場合にプロセスをクラッシュさせていましたが、現在、Windowsは回復できますが、CPUサイクルが追加されます。

整列属性は、整列を強制するGCC固有の機能です(C言語とは関係ありません)。整列とは、データをメモリに配置する必要のある数値の倍数です。次に、コンパイラーはデータ構造にガベージを挿入して、コンパイラーに課した制約が満たされていることを確認します。

あなたの質問の例を見てみましょう:

struct data
{
    int a    __attribute__( ( aligned ( 8 ) ) ) ;
    char ch  __attribute__( ( aligned ( 1 ) ) ) ;
    float s  __attribute__( ( aligned ( 4 ) ) ) ;
} ; 

この場合、架空のプラットフォームのネイティブサイズintとネイティブサイズの両方が4バイトであると想定します。float

メモリに配置された最終的な構造体は、より近くなります

struct data
{
    int a;        // 0x00   
    int junk0     // 0x04
    char ch;      // 0x08
    char junk1[3] // 0x09
    float s;      // 0x0C
} ; 

コンパイラが最初の整数をパディングするかどうかはわかりません。そのため、実際には最終的な構造体で8バイトを占有します。パディングだけで64ビットになるわけではありません。構造体は64ビットアドレスにのみ配置されると想定されるため、奇妙だと思います。したがって、32ビットアーキテクチャでは、メモリを割り当てる場合は、そのメモリが8の倍数であるアドレスに整列されていることはこれでOKです。たぶんそれはそれをよりポータブルにし、32ビットと64ビットで同じように動作することを確認するためです。

コンパイラーは、より積極的になり、実際にはより多くのスペースを浪費することを選択できますが、それに対抗するためのパックディレクティブがあります。ネイティブバイナリ互換性があなたにとって本当に重要であるなら、これらのことは本当に重要です。

于 2012-12-16T14:00:10.847 に答える
1

最初のユースケースは、char何か他のものを格納するために使用する配列がある場合で、適切な型にアラインする必要があります。

2 番目のシナリオはバイナリ プロトコルです。(ネットワークまたはファイルから) 特別にレイアウトされたデータを読み取る場合は、aligned を使用してレイアウトを強制する必要があります。

于 2012-12-16T13:51:09.733 に答える