__int128对齐段故障与gcc -O SSE优化

Bin*_* Wu 1 gcc sse memory-alignment compiler-optimization

__int128用作struct的成员.它可以找到-O0(没有优化).

但是,如果启用了优化(-O1),则会因段故障而崩溃.

它在指令处崩溃movdqa,需要将var对齐16,而地址的分配malloc()仅由8对齐.

我尝试禁用SSE优化-mno-sse,但无法编译:

/usr/include/x86_64-linux-gnu/bits/stdlib-float.h:27:1: error: SSE register return with SSE disabled
Run Code Online (Sandbox Code Playgroud)

所以,我能做些什么,如果我想使用__int128-O1两者兼而有之?

在此先感谢吴

顺便说一下,如果__int128仅在堆栈上使用(不在堆上),似乎没问题.

====编辑====

对不起,我没说实话.

其实我没用过malloc().我使用了一个内存池lib,它返回8对齐的地址.我说malloc()只是为了让事情变得简单.

经过测试,我已经知道它malloc()与16对齐.并且__int128成员也在结构中对齐16.

所以问题是我的内存池lib.

非常感谢.

Pet*_*des 6

对于X86-64系统V,alignof(maxalign_t) == 16所以malloc总是返回16字节对齐的指针.听起来你的分配器坏了,如果用的话也会违反ABI long double.(将其作为答案重新发布,因为事实证明这答案).

返回的内存malloc保证能够保存任何标准类型,因此这意味着如果大小足够大,则足够对齐.

这不能是32位代码,因为gcc不支持__int12832位目标.(32位glibc malloc仅保证8字节对齐.)


通常,如果违反类型的对齐要求,则允许编译器生成出错的代码.在x86上,通常只会使用未对齐的内存,直到编译器使用对齐所需的SIMD指令.即使是错误对齐的自动向量化uint16_t*也可能出错(为什么对mmap的内存进行未对齐访问有时会在AMD64上出现段错误?),所以不要认为窄类型总是安全的.使用memcpy,如果你需要表达C.不对齐的负载


显然alignof(__int128)是16.所以他们没有重复i386 System V中的怪异,即使是8字节对象也只保证4字节对齐,而struct-packing规则意味着编译器不能给它们自然对齐.

这是一件好事,因为它使用SSE进行复制变得高效,并且意味着_Atomic __int128不需要任何额外的特殊处理来避免lock cmpxchg16b缓慢的高速缓存行分裂.