为什么 gcc5 下的 new operator 可以得到 32 byte 对齐的地址(在 x86-64 机器上)

2022-01-05 10:29:34 +08:00
 111qqz

stackoverflow 的提问参考这里

从查阅到的资料中看出,在 x86-64 机器上,gcc 的 new operator 应该是只有 16 byte 对齐的,直到 gcc7 的 c++17 下,由于引入了 aligned new ,才支持更大的对齐 size.

但是我实际发现,gcc5 下得到的地址就已经是 32 byte 对齐了。 测试代码在这里: gcc4.9, gcc5.1

代码跑了上万次,每一次 gcc5 下得到的结果都是 32 byte 对齐,感觉不像是巧合

然后参考了这个帖子, 猜测是 glibc 或者 libstdc++中有相关的更改。

发现 gcc4.9 和 gcc5.1 的 glibc 版本都是 2.19 libstdc++的版本倒是不同,一个是 6.0.20 ,一个是 6.0.21

但是去看了 libstdc++的代码,没有发现和 Gcc5 有关的变更

所以我的问题是,gcc5 下得到的地址有 32 byte 对齐是不是巧合? 是巧合的话,如何能复现出只有 16 byte 对齐的情况? 不是巧合的话, 为什么 gcc4.9 和 gcc5 的行为不一致?

1276 次点击
所在节点    C++
9 条回复
3dwelcome
2022-01-05 10:57:30 +08:00
不懂,你代码里写了 alignas(32)关键字,那就是期望 32 位内存对齐啊。

把关键字去掉,就不是这个结果了。

当然那现在内存不值钱,多浪费点空间没什么。然而对齐了,指令性能和移动端的可移植性,都能得到提升。
yokyj
2022-01-05 11:04:52 +08:00
tql
111qqz
2022-01-05 11:25:29 +08:00
@3dwelcome 在 gcc4.9 下,这个期望是得不到满足的。 就算写了 alignnas(32),得到的地址也只有 16 byte 对齐。
111qqz
2022-01-05 11:25:40 +08:00
@yokyj 太菜了
3dwelcome
2022-01-05 11:34:19 +08:00
gcc4.9 以前一直有对齐关键字,叫__declspec(align(32)),这是很早以前就支持的。

alignnas 这个应该是新编译器才支持的。
111qqz
2022-01-05 14:48:37 +08:00
@3dwelcome 可能我的示例代码有些让人困惑。 我原始的问题是,gcc4.9 下 new 出来的地址是 16 byte 对齐,但是 gcc5 下 new 出来的地址是 32 byte 对齐。 原始问题其实是在使用 avx2 指令时遇到的。avx2 指令要求 32 byte 对齐。如下代码在 Gcc4.9 下由于对齐问题会发生 core ,但是在 gcc5 下不会。
https://godbolt.org/z/xKMYWThYo
111qqz
2022-01-07 10:31:14 +08:00
up
mingl0280
2022-01-12 09:28:48 +08:00
@111qqz GCC4.9 是不是不支持 alignas ?
111qqz
2022-01-12 10:08:45 +08:00
@mingl0280 感觉和 alignas 可能没什么关系? 因为最初的问题其实是在 Gcc4.9 下使用 avx2 指令。Avx2 指令需要 32 位对齐但是 gcc4.9 下只能提供 16 位对齐,导致会发生 core. 可以参考我 6 楼中的代码。 我换了个例子是不想 simd 相关的内容影响问题本身

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/826265

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX