奇怪的GCC行为 [英] Strange GCC Behaviour

查看:142
本文介绍了奇怪的GCC行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下C ++代码:

  struct vertex_type {
float x,y,z;

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

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;当我将(当前注释掉的)构造函数添加到<$ c






$ b < c> vertex_type
struct,它突然在编译时间上升了10-15秒。
Stumped,我查看了由gcc(使用 -S )生成的程序集,并注意到代码生成大小比以前大了几百倍。 p>

  ... 
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)
...



通过省略构造函数定义,生成的程序集完全不同。

  .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。

解决方案

这是一个长期的 GCC中缺少的优化 应该能够为这两种情况生成相同的代码,但不能。



没有构造函数,您的 vertex_type 是一个POD结构,GCC可以在编译时初始化静态/全局实例。使用构造函数,最好的做法是在程序启动时生成初始化全局的代码。


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.

这篇关于奇怪的GCC行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆