Intel® C++ Compiler Classic Developer Guide and Reference

ID 767249
Date 12/16/2022
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

GAP Message (Diagnostic ID 30753)

Message

Convert array of struct "%s" into a new struct whose fields are arrays of the corresponding fields in the original struct. This improves performance due to better data locality.

Advice

You should apply full peeling to a class or structure. This is done by splitting a class or structure into separate fields. This should improve performance by better utilizing the processor cache. This message is generated only when the entire application is built with Interprocedural Optimization (IPO). This transformation requires that you change all access to any peeled structure and its fields in the entire application. In some cases, it may not be easy to change source code to apply full peeling.

Example

Consider the following:

// 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(); 
}

In this case, the compiler tells you to convert struct "S3".

If you determine it is safe to do so, you can modify the program code as follows:

#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(); 
}

Verify

Make sure that the restructured code satisfies the original program semantics.