C++ 数组元素内存对齐
C++ Array Element Memory Alignment
您好,我已经尝试为着色器提供一个数组,例如点光源位置。但是这个着色器希望 vec3 对齐 16 个字节而不是 glm 中的 12 个字节。对于一个 vec3 没有问题,你可以把 "alignas(16)" 放在它前面。但是对于数组,c++ 只是认为整个数组应该按 16 对齐,而不是它的各个元素。
struct Scene {
alignas(16) glm::vec3 lights[2];
};
int main() {
Scene scene;
scene.lights[0] = { 1,2,3 };
scene.lights[1] = { 4,5,6 };
}
我还查看了 visual studio 中的内存调试器,字节被紧密打包,没有任何填充
Screenshot of visual studio memory debugger
我能想到的唯一解决方案是 一个:将 glm 的源代码更改为 16 对齐(这不是一个好主意)
two:创建一个新结构,如“16ByteAlignedVec3”,其中包含 vec3,并将此结构设置为对齐 16。然后将其用作类型数组的
和three:使用指针访问数组数据,如果要访问例如索引1
,则将其递增16字节
But for an array c++ just thinks that the whole array should be aligned by 16 and not its individual elements.
确实如此。这就是为数组指定 alignas
的意思。数组的对齐受到影响;不是元素的对齐方式。
two: to create a new struct like "16ByteAlignedVec3" , which contains the vec3, and setting this struct to have an alignment of 16
这是一个合理的方法。您可以通过使用继承而不是成员使 class 的行为与 glm::vec3 相同:
struct Scene {
struct alignas(16) 16ByteAlignedVec3 : glm::vec3 {};
aligned_vec3 lights[2];
};
您好,我已经尝试为着色器提供一个数组,例如点光源位置。但是这个着色器希望 vec3 对齐 16 个字节而不是 glm 中的 12 个字节。对于一个 vec3 没有问题,你可以把 "alignas(16)" 放在它前面。但是对于数组,c++ 只是认为整个数组应该按 16 对齐,而不是它的各个元素。
struct Scene {
alignas(16) glm::vec3 lights[2];
};
int main() {
Scene scene;
scene.lights[0] = { 1,2,3 };
scene.lights[1] = { 4,5,6 };
}
我还查看了 visual studio 中的内存调试器,字节被紧密打包,没有任何填充
Screenshot of visual studio memory debugger
我能想到的唯一解决方案是 一个:将 glm 的源代码更改为 16 对齐(这不是一个好主意)
two:创建一个新结构,如“16ByteAlignedVec3”,其中包含 vec3,并将此结构设置为对齐 16。然后将其用作类型数组的
和three:使用指针访问数组数据,如果要访问例如索引1
,则将其递增16字节But for an array c++ just thinks that the whole array should be aligned by 16 and not its individual elements.
确实如此。这就是为数组指定 alignas
的意思。数组的对齐受到影响;不是元素的对齐方式。
two: to create a new struct like "16ByteAlignedVec3" , which contains the vec3, and setting this struct to have an alignment of 16
这是一个合理的方法。您可以通过使用继承而不是成员使 class 的行为与 glm::vec3 相同:
struct Scene {
struct alignas(16) 16ByteAlignedVec3 : glm::vec3 {};
aligned_vec3 lights[2];
};