定义
结构填充是根据处理器指定的内存对齐规则对齐结构的数据成员的过程。
英特尔x86处理器的内存对齐规则是什么?
根据我的理解,Intel-x86处理器的自然地址边界各为32位(即
addressOffset%4==0
)所以,在x86处理器中,
struct mystruct_A {
char a;
int b;
char c;
};
将被构建为,
struct mystruct_A {
char a;
char gap_0[3]; /* inserted by compiler: for alignment of b using array */
int b;
char c;
char gap_1[3]; /* for alignment of the whole struct using array */
};
英特尔x86-64处理器的内存对齐规则是什么?
根据我的理解,Intel x86-64处理器的自然地址边界各为64位(即
addressOffset%8==0
)所以,在x86-64处理器中,
struct mystruct_A {
char a;
int b;
char c;
};
将被构建为,
struct mystruct_A {
char a;
char gap_0[7]; /* inserted by compiler: for alignment of b using array */
int b;
char c;
char gap_1[7]; /* for alignment of the whole struct using array */
};
如果上述理解是正确的,那么我想知道为什么使用int数组进行位操作?
建议使用int大小的数据,如上所述here,即,因为对内存的访问最具成本效益是访问整数数据。
问题:
这个内存对齐规则强制为位操作声明int大小的数据吗?
答案 0 :(得分:1)
附录:这对x86 / -64位处理器有效,对其他处理器也有效。我盲目地假设你正在使用它们。对于其他人,您应该查看相应的手册。
如果fasm自动将填充物添加到我的结构中,我就会疯狂。通常,当访问内存位于与要检索的元素大小相对应的边界上时,性能会更好。话虽这么说,但这不是必然的!
这篇文章可能值得一看:https://software.intel.com/en-us/articles/coding-for-performance-data-alignment-and-structures
英特尔关于优化布局的建议是首先从最大的元素开始,然后随着结构的增加而变小。这样,只要第一个元素正确对齐,您就可以保持正确对齐。没有三字节元素,因此不对齐是不可能的,所有编译器可能会做的是在最后添加字节,这是确保它不会破坏事情的最好方法,如果你选择直接做内存访问而不是使用变量。
最安全的程序是不依赖于您的编译器,而是自己正确地对齐数据。
有趣的事实:循环以相同的方式工作。在循环开始之前,在代码中填充NOP可以产生影响。