开发者

Strange GCC Behaviour

Given the following C++ code:

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;
}

When I added the (currently commented out) constructors into the vertex_type struct, it abruptly 10-15 second rise in compilation time. Stumped, I looked to the assembly generated by gcc (using -S), and noticed that code-gen size was several hundred times bigger than before.

...
movl    $0x3f800000, cube+84(%rip)
movl    $0x3f800000, cube+88(%rip)
movl    $0x3f800000, cube+92(%rip)
movl    $0x00000000, cube+96(%rip)
...
movl    $0x00000000, cube+119996(%rip)
...

By leaving out the constructor definition, the generated assembly was completely different.

.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

Obviously there is a significant difference in the code generated by the compiler. Why is that? Also, why does gcc zero all the elements in one situation and not the other?

edit: I am using the following compiler flags: -std=c++0x with g++ 4.5.2.


This is a long-standing missing optimization in GCC. It should be able to generate the same code for both cases, but it can't.

Without the constructors, your vertex_type is a POD structure, which GCC can initialize static/global instances of at compile time. With the constructors, the best it can do is generate code to initialize the global at program startup.


If you have custom constructor, the compiler should call it for all vector it create. If you don't write your own, it default to a generated constructor. But as no type are complex, it just don't need to call it. And the array is store as a constant table in the binary.

Try inlining your default constructor and let it empty. Of course, it may only work wit h optimization enabled

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜