【问题标题】:C array vs structC数组与结构
【发布时间】:2017-03-26 21:52:02
【问题描述】:

我目前正在开发一个 OpenGL 应用程序。到目前为止,在编写 API 时一切都运行良好。

对于通常的数据类型,我使用结构。例如:

struct vec3 {
 GLfloat x;
 GLfloat y;
 GLfloat z;
}

但现在我考虑使用与简单数组相同的数据类型,例如

typedef GLfloat vec3[3];

我真的很喜欢将类型作为简单的数组来处理,因为它更容易访问它们,我什至可以使用循环来修改它们的值(例如在 GLfloat 矩阵 [16] 中) 但是让我烦恼的是C不允许返回数组,所以我必须自己提供存储操作 mat4_identity(mat4输出) 有了一个结构,我可以很容易地说

mat4 m = mat4_identity() clean and nicely.

我现在的问题是:哪一个在性能方面更好(当然,例如,当有很多顶点时,我只能想到繁重的结构指针取消引用 + 访问)以及我最终应该为我的 OpenGL API 实际使用哪一个.

【问题讨论】:

  • 你考虑过struct vec3 { GLfloat vec3[3]; } 吗?
  • @chux 是的,但这对我来说更像是一个奇怪的黑客/解决方法。理想的情况是我可以使用结构但像数组一样访问它们(显然,当它们都由具有相同数据类型的变量组成时)。不幸的是,这也不起作用,因为我听说结构内部有特殊的对齐或包装。
  • struct vec3 { union { struct { float x, y, z; }; float a[3]; };
  • @Joe 你忘了大括号:|此外,sizeof(struct xyz) 不必等于 sizeof(array),因此对结构的写入不会映射到数组。
  • 是的,我确实忘记了一个,但原理很清楚。编译器没有理由布局只有一种类型的结构与相同类型的数组不同。在任何普通编译器上,这成为问题的可能性非常非常低。

标签: c arrays performance opengl struct


【解决方案1】:

如果您使用的是 C11,则可以两全其美!

union vec3 {
        struct {
            float x, y, z;
        };
        float xyz[3];
};

然后你可以通过任何一种方式访问​​它们:

printf("%f %f %f\n", vec.x, vec.y, vec.z);
printf("%f %f %f\n", vec.xyz[0], vec.xyz[1], vec.xyz[2]);

如果你不使用C11,你仍然可以这样做,但必须命名具有三个组件的结构:

union vec3 {
    struct {
        float x, y, z;
    } components;
    float xyz[3];
}

至于效率,数组保证是连续的(元素之间没有间隙),而结构则不是,所以结构可能会浪费更多的内存。但考虑到现代计算机的内存量,我怀疑这是一个问题。

另外请注意,虽然数组衰减为指针,但结构并不能保证这样做。除非结构适合寄存器(vec3 可能不适合),否则您应该将指针传递给它,而不是按值传递。

【讨论】:

  • 它是否保证例如 vec3.components.y == vec3.xyz[1] 或者对齐会破坏一切?
  • 按值传递通常会更有效,因为编译器可以更容易地证明没有出现别名。
  • @MuradBabayev 正如我已经评论过你的问题,对齐不会破坏任何东西,因为编译器没有理由添加填充(对齐要求永远不会大于对象的大小)
猜你喜欢
  • 2012-02-28
  • 2013-07-29
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多