在Linux上,我想知道在页面边界上,某些对象类型是否总是可以分配的。对于哪种C类型,这总是有保证的吗?请向我指出以下答案的标准/文件。
澄清守则:
#include <sys/mman.h>
#include <string.h>
typedef char TYPE;
int main()
{
TYPE val;
void *mem;
mem = mmap(NULL, sizeof(val), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
memcpy(mem, &val, sizeof(val));
/* is *(TYPE*)mem guaranteed to be the same as val ? */
}char的答案是肯定的,肯定的。
对于其他哪种类型,答案是肯定的,保证?
发布于 2022-12-01 21:40:58
对象对齐需求由硬件体系结构(正在使用的处理器)决定,因为处理器可能无法从未对齐地址加载数据。(在某些情况下,内核可以通过通过未对齐地址捕获访问尝试生成的处理器中断来提供对齐地址支持,并模拟指令。然而,这是缓慢的。
Linux内核支持的硬件体系结构在https://www.kernel.org/doc/html/latest/arch.html中列出。
总之,Linux支持的硬件体系结构不需要处理器支持的任何原生数据类型超过128字节的对齐,页面大小是512字节的倍数(出于历史原因),因此我们可以明确地说,在Linux上,所有数据原语都可以在对页地址上访问。
(在Linux中,您可以使用(页大小)获取页面大小。请注意,如果支持巨大的页面,则它们更大,是此值的倍数。)
上述内容涵盖了GNU C标准库及其扩展定义的所有C数据类型,因为它们只定义标量类型、元素在自然边界上对齐的结构(未打包)和向量化类型(使用为SIMD体系结构设计的GCC/Clang矢量扩展)。
(使用GCC 类型或变量 属性,您可以定义一个必须在非对齐地址分配的打包结构(如果您真的是邪恶的)。)
如果我们查看C标准,类型max_align_t (编译器在<stddef.h>中提供;即使在标准C库不可用的独立环境中也是可用的)对任何对象都具有最大的对齐性(除了上面提到的构造错误的打包结构)。
这意味着_Alignof (max_align_t)告诉您C标准定义的类型所需的最大对齐。(请记住告诉C编译器代码使用了C11标准或更高版本提供的特性,例如-std=c11或-std=gnu2x。)
然而,某些使用SIMD (单指令、多数据)的体系结构-- GCC和其他C编译器已经为其添加了向量扩张,例如实现Intel <immintrin.h> MMX/SSE/AVX等内在结构--可能需要更大的矢量寄存器对齐,直到矢量寄存器的大小。(这是512位数据的来源。)在x86-64 (目前使用的64位Intel和AMD体系结构)上,对于非对齐访问和对齐访问有单独的指令,而非对齐访问可能比对齐访问慢,具体取决于处理器。因此,使用C标准的向量扩展,_Alignof(max_align_t)不适用于这些向量化类型。
https://stackoverflow.com/questions/74637462
复制相似问题