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

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

メッセージ

構造体 '%s' の配列を、オリジナルの構造体フィールドの配列をフィールドとする新しい 1 つの構造体に変換します。 これによりデータの局所性が向上し、パフォーマンスが改善されます。

アドバイス

クラスまたは構造体に完全なピーリングを適用してみてください。これは、クラスまたは構造体を個々のフィールドに分割することで行えます。 これにより、プロセッサー・キャッシュがより活用され、パフォーマンスが向上するでしょう。 このメッセージは、アプリケーション全体でプロシージャー間の最適化 (IPO) を有効にしてビルドした場合のみ生成されます。 この変換では、アプリケーション全体でピーリングされた構造体とそのフィールドへのアクセスを変更する必要があります。 場合によっては、完全なピーリングを適用するためにソースコードを変更することは容易ではありません。

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

// peel.c 
#include <stdio.h> 
#include <stdlib.h>
 
#define N 100000 
int a[N]; 
double b[N]; 
struct S3 {
    int *pi;
    double d;
    int j; 
};
 
struct S3 *sp;
 
void init_hot_s3_i() {
 
    int ii = 0;
 
    for (ii = 0; ii < N; ii++) {
        sp[ii].pi = &a[ii];
    } 
} 
void init_hot_s3_d() {
    int ii = 0;
 
    for (ii = 0; ii < N; ii++) {
        sp[ii].d = b[ii];
    } 
} 
void init_hot_s3_j() {
    int ii = 0;
 
    for (ii = 0; ii < N; ii++) {
        sp[ii].j = 0;
    } 
} 
void dump_s3() {
    int ii;
 
    for (ii = 0; ii < N; ii++) {
        printf("i= %d ", *(sp[ii].pi));
        printf("d= %g \n", sp[ii].d);
        printf("j= %g \n", sp[ii].j);
    } 
}
 
main() {
 
   sp = (struct S3 *)calloc(N, sizeof(struct S3));
   init_hot_s3_i();
   init_hot_s3_d();
   init_hot_s3_j();
   dump_s3(); 
}

この例では、コンパイラーにより構造体 "S3" を変換するように指示されます。

安全であることが分かっている場合は、次のようにプログラムコードを変更します。

#include <stdio.h> 
#include <stdlib.h>
 
#define N 100000 
int a[N]; 
double b[N]; 
struct S3 {
    int *pi; 
}; 
struct new_d {
    double d; 
}; 
struct new_j {
    int j; 
};
 
struct S3 *sp; 
struct new_d *sp_d; 
struct new_j *sp_j;
 
void init_hot_s3_i() {
 
    int ii = 0;
 
    for (ii = 0; ii < N; ii++) {
        sp[ii].pi = &a[ii];
    } 
} 
void init_hot_s3_d() {
    int ii = 0;
 
    for (ii = 0; ii < N; ii++) {
        sp[ii].d = b[ii];
    } 
} 
void init_hot_s3_j() {
    int ii = 0;
 
    for (ii = 0; ii < N; ii++) {
        sp[ii].j = 0;
    } 
} 
void dump_s3() {
    int ii;
 
    for (ii = 0; ii < N; ii++) {
        printf("i= %d ", *(sp[ii].pi));
        printf("d= %g \n", sp[ii].d);
        printf("j= %g \n", sp[ii].j);
    } 
}
 
main() {
 
   sp = (struct S3 *)calloc(N, sizeof(struct S3));
   init_hot_s3_i();
   init_hot_s3_d();
   init_hot_s3_j();
   dump_s3(); 
}

確認

このコード変更によってオリジナルのプログラムのセマンティクスが変更されないことを確認してください。