作者:马璐720 | 来源:互联网 | 2022-12-03 17:45
我__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
所以,我能做些什么,如果我想使用__int128
和-O1
两者兼而有之?
在此先感谢吴
顺便说一下,如果__int128
仅在堆栈上使用(不在堆上),似乎没问题.
====编辑====
对不起,我没说实话.
其实我没用过malloc()
.我使用了一个内存池lib,它返回8对齐的地址.我说malloc()
只是为了让事情变得简单.
经过测试,我已经知道它malloc()
与16对齐.并且__int128
成员也在结构中对齐16.
所以问题是我的内存池lib.
非常感谢.
1> Peter Cordes..:
对于X86-64系统V,alignof(maxalign_t) == 16
所以malloc
总是返回16字节对齐的指针.听起来你的分配器坏了,如果用的话也会违反ABI long double
.(将其作为答案重新发布,因为事实证明这是答案).
返回的内存malloc
保证能够保存任何标准类型,因此这意味着如果大小足够大,则足够对齐.
这不能是32位代码,因为gcc不支持__int128
32位目标.(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
缓慢的高速缓存行分裂.