英特尔从未在同一 CPU 的未来版本中删除指令集。即,在旧 Intel CPU 上运行的二进制文件始终可以在较新的 Intel CPU 上运行。
(第一代 Xeon Phi 是一个例外:Knight's Corner 使用了 AVX512 的不兼容变体,称为 KNI,但后来的 Xeon Phi 加速卡/计算机使用 AVX512。)
如果必须在所有 CPU 上使用相同的二进制文件,use gcc -march=sandybridge -mtune=haswell
,并确保重要数组按 32 字节对齐。
也许值得进行基准测试gcc -march=sandybridge
(即使用tune=sandybridge),看看哪个更适合您的代码。-mprefer-avx128
or -mprefer-vector-width=256
尝试一下可能很有趣:当 gcc 使用 256 位向量自动向量化时,一些循环会变得混乱。
SnB/IvB 的 AVX 加载/存储未对齐,效率低下,因此调整=sandybridge 集-mavx256-split-unaligned-load
,如果你的数据很糟糕is在运行时对齐,但编译器不知道这一点。额外的指令和随机播放对 Haswell 没有帮助,所以-mtune=haswell
包括-mno-avx256-split-unaligned-load
.
不幸的是,gcc 没有“tune=avx2”选项来调整所有具有 AVX2 的 CPU,也没有选项来调整支持您启用的指令集的普通 CPU。https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568。您唯一的选择是针对特定 CPU 进行调整,或者针对通用基准进行调整,或者使用特定的调整选项。
Gcc 确实对运行时调度有一些支持ifunc
您必须在源中激活它才能实现特定功能。看https://lwn.net/Articles/691932/ https://lwn.net/Articles/691932/有关函数多版本控制的更多信息。
最佳选择:为 SnB / Haswell 构建单独的二进制文件,并使用脚本或$PATH
setting
在每个集群节点上创建一个/etc/host-type
或其他什么,其中有sandybridge
or haswell
管他呢。任何每个节点的文件系统都可以,或者在运行时重新检测它gcc
或者更便宜的东西。在您的作业脚本中:
#!/bin/sh
bin_dir="./bin-$(</etc/node-type)"
exec "$bin_dir/my_prog" "$@"
根据需要创建符号链接bin-skylake
and bin-broadwell
使用 Haswell 二进制文件。
Haswell推出了AVX2和FMA,以及BMI1/2。如果您需要处理数字,那么您确实需要 FMA。 BDW/SKL 没有引入任何重要的 ISA 扩展,编译器可以使用这些扩展来使代码运行得更快。 BDW/SKL 的调整也没有什么不同。
如果您有 Skylake-avx512 CPU,那就不同了。