c - GCC最高指令集兼容多种架构
问题描述
我正在由具有不同架构的机器组成的集群上运行作业:
gcc -march=native -Q --help=target | grep -- '-march=' | cut -f3
给我以下之一:broadwell
、haswell
、ivybridge
或.sandybridge
skylake
可执行文件必须相同,所以我不能使用-march=native
,但同时架构有共同点(我认为它们都支持 AVX?)。
我知道gcc
(与 Intel 相反icc
)不允许在单个可执行文件中使用多个架构。我想知道的是,是否有办法要求gcc
与上面列出的所有架构兼容的最高指令集。
gcc 版本:8.1.1
解决方案
英特尔从未在同一 CPU 的未来版本中删除指令集。即适用于旧英特尔 CPU 的二进制文件始终适用于较新的英特尔 CPU。
(唯一的例外是第一代 Xeon Phi:Knight's Corner 使用了不兼容的 AVX512 变体,称为 KNI,但后来 Xeon Phi 加速卡/计算机使用 AVX512。)
如果您必须在所有 CPU 上使用相同的二进制文件,请使用gcc -march=sandybridge -mtune=haswell
,并确保您的重要数组按 32 个字节对齐。
也许也值得用gcc -march=sandybridge
(即使用 tune=sandybridge)进行基准测试,看看哪个更适合您的代码。 -mprefer-avx128
或者-mprefer-vector-width=256
尝试一下可能会很有趣:当 gcc 使用 256 位向量自动向量化时,一些循环会变得混乱。
SnB/IvB 的 AVX 加载/存储效率低下,因此 tune=sandybridge sets -mavx256-split-unaligned-load
,如果您的数据在运行时对齐但编译器不知道,这会很糟糕。额外的指令和洗牌对 Haswell 没有帮助,所以-mtune=haswell
包括-mno-avx256-split-unaligned-load
.
不幸的是,gcc 没有“tune=avx2”选项来调整所有具有 AVX2 的 CPU,或者调整支持您启用的指令集的平均 CPU 的选项。 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568。您唯一的选择是针对特定 CPU 进行调整,或者针对通用基线进行调整,或者使用特定的调整选项。
Gcc 确实对运行时调度有一些支持ifunc
您必须在源中激活它才能使用特定功能。有关函数多版本控制的更多信息,请参阅https://lwn.net/Articles/691932/ 。
最佳选择:为 SnB / Haswell 构建单独的二进制文件,并使用脚本或$PATH
设置进行调度
在每个集群节点上,创建一个/etc/host-type
或任何东西,它具有sandybridge
或haswell
或任何东西。任何每个节点的文件系统都可以,或者在运行时重新检测它gcc
或更便宜的东西。在您的工作脚本中:
#!/bin/sh
bin_dir="./bin-$(</etc/node-type)"
exec "$bin_dir/my_prog" "$@"
根据需要创建符号链接以制作bin-skylake
和bin-broadwell
使用 Haswell 二进制文件。
Haswell 推出了 AVX2 和 FMA,以及 BMI1/2。如果您正在处理数字,您真的想要 FMA。BDW/SKL 没有引入任何重要的 ISA 扩展,编译器可以使用这些扩展来使您的代码运行得更快。BDW/SKL 的调整也没有什么不同。
如果您有任何 Skylake-avx512 CPU,那就不同了。
推荐阅读
- java - 我收到一个错误->。有人可以帮我吗?
- javascript - 在 CSS 文件中的 vscode 上显示 { 预期 css(css-lcurlyexpected) 时出错
- python-3.x - Django Graphene 使用多层嵌套外键编写突变
- html - 取决于窗口宽度的一两个广告 - 可能吗?
- python - 在 for 循环中对数字进行排序,同时保留索引值
- ios - 如何从终端/外壳完全降级 xcode?
- javascript - 为什么我的 Async 方法没有从另一个屏幕上使用 react native 中的功能组件调用?
- css - 在反应应用程序中包含样式表文件时出现问题
- typescript - react-admin typescript:不能使用命名空间作为类型
- java - 没有这样的列 SQLite Android