インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

GAP メッセージ (診断 ID 30754)

メッセージ

フィールド '%s' (構造体 '%s') を 8 バイト境界でアライメントすることでパフォーマンスが向上します。IA-32 プラットフォームの Linux* では、倍精度浮動小数点データのデフォルトのアライメントは 4 バイトです。[別の方法] 構造体フィールドの順序を変更することで倍精度浮動小数点データを 8 バイト境界にアライメントします。[別の方法] __attribute__((aligned(8))) を使用して、フィールド '%s' (構造体 '%s') を 8 バイト境界上に割り当てます。

このメッセージは、Linux* システムでのみ出力されます。

アドバイス

クラスまたは構造体のフィールドを並べ替えて "倍精度" フィールドを 8 バイト境界でアライメントする必要があります。IA-32 アーキテクチャー・ベースの Linux* システムでは、"倍精度" フィールドを 8 バイト境界にアライメントする必要はありません。ただし、そうすることによって並列化などの最適化を有効にし、より良いコードを生成します。並べ替えを行う前に、構造体フィールドが特定の順序でなければならないかどうかアプリケーション・コードを確認する必要があります。

次の例について考えてみます。

//alignment.c 
#include <stdlib.h> 
#include <stdio.h>
 
#define N 1000
 
struct S {
    int i;
    double d1;
    double d2;
    double d3; 
};
 
struct S *sp;
 
static struct S* 
alloc_s(int num) {
    struct S * temp;
 
    temp = calloc(num, sizeof(struct S));
    return temp; 
}
 
struct S temp;
 
static void 
swap_s(int i, int j) {
    memcpy(&temp, sp + i, sizeof(struct S));
    memcpy(sp + i, sp + j, sizeof(struct S));
    memcpy(sp+ j, &temp, sizeof(struct S)); 
}
 
static void 
init_s(int num) {
    int ii;
 
    for (ii = 0; ii < num; ii++) {
        sp[ii].i = ii;
        sp[ii].d1 = (double) ii + 1;
        sp[ii].d2 = (double) ii + 2;
        sp[ii].d3 = (double) ii + 3;
    } 
}
 
main() {
    int ii;
    double d = 0.0;
 
    sp = alloc_s(N);
 
    for(ii = 0; ii < N -1; ii += 2) {
        swap_s(ii, ii+1);
    }
 
    for (ii = 0; ii < N ; ii++) {
        sp[ii].d1 = sp[ii].d1 * sp[ii].d2 * sp[ii].d3;
        d += sp[ii].d1;
    }
 
    for (ii = 0; ii < N ; ii++) {
        printf(" %d:  %g   %g  %g  \n", sp[ii].i, sp[ii].d1, sp[ii].d2, sp[ii].d3);
    } 
}

このプログラムをコンパイルすると、コンパイラーは「フィールド 'd1, d2, d3' (構造体 'S') を 8 バイト境界でアライメントすることでパフォーマンスが向上します。」というメッセージを生成します。

別の方法として、'__attribute__((aligned(8)))' を使用して 'd1, d2, d3' を 8 バイト境界でアライメントできます。この処理を行う 1 つの方法を次に示します。

struct S {
    int i;
    __attribute__((aligned(8)))  double d1;
    double d2;
    double d3; 
};

確認

このコード変更によってオリジナルのプログラムのセマンティクスが変更されないことを確認してください。アライメントの変更によって構造体のサイズが変更されることがあります。構造体のレイアウト変更によってオリジナルのプログラムのセマンティクスが変更されないことを確認してください。