Странное поведение GCC - PullRequest
18 голосов
/ 06 октября 2011

Учитывая следующий код C ++:

struct vertex_type {
    float x, y, z;

    //vertex_type() {}
    //vertex_type(float x, float y, float z) : x(x), y(y), z(z) {}
};

typedef struct {
    vertex_type vertex[10000];
} obj_type;

obj_type cube = {
    {
        {-1, -1, -1},
        {1, -1, -1},
        {-1, 1, -1},
        {1, 1, -1},

        {-1, -1, 1},
        {1, -1, 1},
        {-1, 1, 1},
        {1, 1, 1}
    }
};

int main() {
    return 0;
}

Когда я добавил (в настоящее время закомментированные) конструкторы в структуру vertex_type, это резко увеличило время компиляции на 10-15 секунд.Ошеломленный, я посмотрел на сборку, сгенерированную gcc (используя -S), и заметил, что размер кода поколения был в несколько сотен раз больше, чем прежде.сборка была совершенно другой.

.globl cube
    .data
    .align 32
    .type   cube, @object
    .size   cube, 120
cube:
    .long   3212836864
    .long   3212836864
    .long   3212836864
    .long   1065353216
    .long   3212836864
    .long   3212836864
    .long   3212836864
    .long   1065353216
    .long   3212836864
    .long   1065353216
    .long   1065353216
    .long   3212836864
    .long   3212836864
    .long   3212836864
    .long   1065353216
    .long   1065353216
    .long   3212836864
    .long   1065353216
    .long   3212836864
    .long   1065353216
    .long   1065353216
    .long   1065353216
    .long   1065353216
    .long   1065353216
    .zero   24
    .text

Очевидно, что существует значительная разница в коде, сгенерированном компилятором.Это почему?Кроме того, почему gcc обнуляет все элементы в одной ситуации, а не в другой?

edit: Я использую следующие флаги компилятора: -std=c++0x с g ++ 4.5.2.

Ответы [ 2 ]

14 голосов
/ 06 октября 2011

Это давняя отсутствующая оптимизация в GCC .Он должен иметь возможность генерировать один и тот же код для обоих случаев, но не может.

Без конструкторов ваш vertex_type является структурой POD, которую GCC может инициализировать static /глобальные экземпляры во время компиляции.С конструкторами, лучшее, что он может сделать, это сгенерировать код для инициализации глобального при запуске программы.

0 голосов
/ 06 октября 2011

Если у вас есть собственный конструктор, компилятор должен вызывать его для всех векторов, которые он создает.Если вы не пишете свой собственный, он по умолчанию для сгенерированного конструктора.Но поскольку ни один тип не является сложным, его просто не нужно вызывать.И массив хранится как двоичная таблица констант.

Попробуйте встроить конструктор по умолчанию и оставить его пустым.Конечно, он может работать только с включенной оптимизацией

...