我已经看过无数的问题形式“我不喜欢填充如何将其关闭”,但还没有找到任何关于强制编译器提供额外填充的内容。
我看起来像
的具体情况struct particle{
vect2 s;
vect2 v;
int rX;
int rY;
double mass;
int boxNum;
};
vect2
是一个简单的struct {double x; double y;} vect2
。为了使用SSE2,我需要能够加载一对双精度数,对齐到16字节边界。这曾经工作,直到我添加额外的int
,将我的结构大小从48字节推到56字节。结果是段错误。
是否有某种编译器指令我可以使用“填充此结构使其成为16字节长的倍数”,或“此结构具有16字节的对齐”?我知道我可以手动完成(例如,添加一个额外的字符[12]),但我真的只是告诉编译器(GCC,最好是ICC兼容),如果我改变它,就不必手动完成未来的结构。
答案 0 :(得分:8)
您可以嵌套两个结构来自动填充它,而无需自己跟踪大小。
struct particle
{
// ...
};
{
particle p;
char padding[16-(sizeof(particle)%16)];
};
如果结构已经是16的倍数,那么这个版本增加了16个字节。这是不可避免的,因为标准不允许零长度的数组。
有些编译器允许零长度数组作为扩展,在这种情况下,您可以这样做:
struct particle_wrapper
{
particle p;
char padding[sizeof(particle)%16 ? 16-(sizeof(particle)%16) : 0];
};
如果结构已经是16的倍数,则此版本不会添加任何填充字节。
答案 1 :(得分:5)
在gcc
中,您可以将任意类型和变量与__attribute__((aligned(...)))
对齐。对于您的示例,这将是
struct particle{
vect2 s;
vect2 v;
int rX;
int rY;
double mass;
int boxNum;
} __attribute__((aligned (16)));
这会自动填充结构体,以使其数组正确对齐。
答案 2 :(得分:3)
我正在为此添加自己的答案,以防有人来寻找解决方案。马克的解决方案是一个很好的解决方案,并满足自动要求,但它不是我最终的时候。我想避免这种情况,这就是为什么我问这个问题,但是有一个“微不足道”的解决方案:
struct particle{
vect2 s;
vect2 v;
int rX;
int rY;
double mass;
int boxNum;
char padding[12];
};
通过手动检查struct
的当前大小,您可以添加适当数量的字符(或其他任何内容,但char
允许您以字节为单位),以使其成为可能合适的大小。这显示了最佳性能以及简单性,即使每次结构更改时都需要更新。在这种情况下,这很好,但如果你有一个结构可以根据选项改变大小,那将是有问题的。
请注意,我的struct
是56个字节,我添加了12个来使其成为64.这个数学不起作用,因为尾随int
已被4个字节填充到8个 - 边界; struct
实际上只有52个字节。只添加5 char
s就可以了,通过使struct
57个字节长,这将被填充到64,但这不是一个很好的解决方案,这就是为什么我用12来让它完全解决。
答案 3 :(得分:1)
新的C ++ 11规范也有new feature,但我不相信很多供应商已经实现了它们。
您可以尝试使用pack pragma,但规范不支持。 GCC和MS都支持它。
这会在1字节边界上对齐结构,但您可以将数字更改为您想要的任何内容。
#pragma pack(push,1)
// ...
#pragma pack(pop)
更新
显然上面的内容不会起作用,因为它只会缩小填充,从不扩展它。遗憾的是,我今天下午没有测试环境。
也许使用匿名联盟会起作用。我知道它会扩大到最大尺寸,但我不知道你是否得到任何关于对齐的保证。
template<typename T, size_t padding_size>
struct padded_field {
union {
T value;
uint8_t padding[padding_size];
};
};
答案 4 :(得分:1)
未经测试,但这可能有效:
#include <xmmintrin.h>
struct particle{
union {
vect2 s;
__m128 s_for_alignment;
};
union {
vect2 v;
__m128 v_for_alignment;
};
...
};
我知道gcc之前有正确对齐__m128
的问题,但现在应该修复这些问题。