且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

针对不同缓冲区大小的不同内存对齐方式

更新时间:2023-11-07 23:50:52

The x86-64 System V ABI requires 16-byte alignment for local or global arrays that are 16 bytes or larger, and for all C99 VLAs (which are always local).

数组使用与元素相同的对齐方式,只是局部数组或全局数组长度至少为16个字节的数组变量或C99可变长度的数组变量始终至少对齐16个字节. 4

4 对齐要求允许在对阵列进行操作时使用SSE指令.编译器通常无法计算可变长度数组(VLA)的大小,但可以预期大多数VLA至少需要16个字节,因此强制要求VLA具有以下要求是合乎逻辑的至少16字节的对齐方式.

4 The alignment requirement allows the use of SSE instructions when operating on the array. The compiler cannot in general calculate the size of a variable-length array (VLA), but it is expected that most VLAs will require at least 16 bytes, so it is logical to mandate that VLAs have at least a 16-byte alignment.

小于一个SIMD向量(16个字节)的固定大小的数组没有此要求,因此可以在堆栈布局中高效打包.

Fixed-size arrays smaller than one SIMD vector (16 bytes) don't have this requirement, so they can pack efficiently in the stack layout.

请注意,此 不适用于内部结构 中的数组,仅适用于局部变量和全局变量.

Note that this doesn't apply to arrays inside structs, only to locals and globals.

(对于动态存储, malloc 返回值的对齐方式必须足够对齐,以容纳不超过该大小的任何对象,并且由于x86-64 SysV具有 maxalign_t 对于16个字节, malloc 如果大小为16或更大,还必须返回16个字节的对齐指针.对于较小的分配,如果需要,对于8B分配,它只能返回8B对齐.)

(For dynamic storage, the alignment of a malloc return value must be aligned enough to hold any object up to that size, and since x86-64 SysV has maxalign_t of 16 bytes, malloc must also return 16-byte aligned pointers if the size is 16 or higher. For smaller allocations, it could return only 8B-aligned for an 8B allocation if it wanted to.)

对本地数组的要求使得可以安全地编写将其地址传递给需要16字节对齐的函数的代码,但这绝不是ABI本身真正需要指定的内容.

The requirement for local arrays makes it safe to write code that passes their address to a function that requires 16-byte alignment, but this is mostly not something the ABI itself really needs to specify.

不同的编译器不必同意将它们的代码链接在一起,结构布局或调用约定的方式(调用寄存器被调用,或用于arg传递...)都不需要达成共识.编译器基本上拥有其正在编译的函数的堆栈布局,而其他函数则不能假定或依赖于此.如果您将指针作为函数args传递或将指针存储到全局变量中,则它们只会获取指向本地var的指针.

It's not something that different compilers have to agree on to link their code together, the way struct layout or the calling convention is (which registers are call-clobbered, or used for arg-passing...). The compiler basically owns the stack layout for the function it's compiling, and other functions can't assume or depend on anything about it. They'd only get pointers to your local vars if you pass pointers as function args, or store pointers into globals.

为全局变量指定它很有用:尽管如此,即使对象文件中的 extern int [] ,即使编译器生成的自动矢量化代码都可以对全局数组进行对齐,这也是安全的由另一个编译器编译.

Specifying it for globals is useful, though: it makes it safe for compiler-generated auto-vectorized code to assume alignment for global arrays, even when it's an extern int[] in an object file compiled by another compiler.