首页 > 解决方案 > 如何正确确定 Intel 处理器的 -march 和 -mtune?

问题描述

我目前正在从源代码构建一个对我来说性能至关重要的软件。因此,我想优化它以在我的特定 Intel CPU 上运行。构建过程需要我设置 -march 和 -mtune 标志。

如果在我的处理器节点上我使用

gcc -march=native -Q --help=target|grep march
gcc -mtune=native -Q --help=target|grep mtune

我得到了 March 的“core-avx2”和 mtune 的“generic”。然而随着

cat /proc/cpuinfo

我得到:

processor   : 23
vendor_id   : GenuineIntel
cpu family  : 6
model       : 63
model name  : Intel(R) Xeon(R) CPU E5-2670 v3 @ 2.30GHz
stepping    : 2
microcode   : 0x3d
cpu MHz     : 2599.993
cache size  : 30720 KB
physical id : 1
siblings    : 12
core id     : 13
cpu cores   : 12
apicid      : 58
initial apicid  : 58
fpu     : yes
fpu_exception   : yes
cpuid level : 15
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt xsave avx f16c rdrand lahf_lm abm epb intel_ppin ssbd ibrs ibpb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup_llc dtherm ida arat pln pts
bogomips    : 4599.35
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

通过转到 Intel(R) Xeon(R) CPU E5-2670 v3 @ 2.30GHz 的主页 ( https://ark.intel.com/content/www/de/de/ark/products/81709/intel-xeon -processor-e5-2670-v3-30m-cache-2-30-ghz.html ) 我发现:代号 -> Products 以前 haswell

如果我使用

gcc -march=haswell -Q --help=target|grep march
gcc -mtune=haswell -Q --help=target|grep mtune

我对两者都有“haswell”。那么我真的不应该使用 haswell 作为 March 而不是 core-avx2 吗?最好的选择是什么?

顺便说一句,我在 CentOS7 上使用 GCC 4.8.5。

谢谢!

编辑:

gcc -march=native -Q --help=target | grep -- '-march=' | cut -f3

-> 核心-avx2

gcc -mtune=native -Q --help=target | grep -- '-mtune=' | cut -f3

-> 通用

标签: performancegccx86intelcompiler-optimization

解决方案


在您使用的 gcc 版本中,Haswell 被称为 core-avx2。其他微架构也有蹩脚的名字。例如,Ivy Bridge、Sandy Bridge 和 Westmere 分别被称为 core-avx-i、corei7-avx 和 corei7。从 gcc 4.9.0 开始,使用微架构的实际名称,因此当gcc -march=native -Q --help=target|grep march在 Haswell 处理器而不是 core-avx2 上使用时,gcc 将打印 Haswell(请参阅补丁)。

当传递-mtune=native给 gcc 并且您正在使用的 gcc 版本不知道主机处理器时,它将应用generic调整。您的处理器型号 (63) 只有 gcc 5.1.0 及更高版本才知道(请参阅补丁)。

的名称打印部分-Q --help=target必须为-march=native. 对于您的 GCC 无法特别识别的太新的 CPU,如果处理器支持 ADX,它将选择 Broadwell 之类的东西,或者支持主机处理器支持的最高 SIMD 扩展(最高 AVX2)的微架构(由 确定cpuid)。

但实际效果-march=native启用所有适当的-mavx -mpopcnt -mbmi2 -mcx16等等选项,都使用单独检测cpuid。因此,出于代码生成的目的,-march=native始终可以启用 GCC 知道如何使用的 ISA 扩展,即使它无法识别您的 CPU。

但是对于设置tune选项,-march=native或者-mtune=native完全失败并回退到generic它无法准确识别您的 CPU 时。不幸的是,它不会tune=intel为未知的英特尔 CPU 做类似的事情。


在您的处理器上,gcc 知道它支持 AVX2,因此它假定它是 Haswell 处理器(在您的 gcc 版本中称为 core-avx2),因为从 Haswell 开始支持 AVX2,但它不确定它实际上是Haswell 处理器。这就是为什么它应用通用调优而不是调优core-avx2(即Haswell)。但在这种情况下,我认为这与调整 core-avx2 的效果相同,因为对于那个编译器版本,只有 Haswell 支持 AVX2,并且编译器知道主机处理器支持 AVX2。但是,一般来说,即使-march在未知 CPU 上被正确猜测,它也可能不会针对本机微架构进行调整。

(编者注:不,tune=generic不适应启用了​​哪些指令集选项。它仍然是完全通用的调整,包括关心不支持 AVX2 的 AMD Phenom 或 Intel Sandybridge 等 CPU。请参阅https://gcc.gnu .org/bugzilla/show_bug.cgi?id=80568为什么 gcc 不将 _mm256_loadu_pd 解析为单个 vmovupd

这是您应该使用or (使用足够新的 gcc)的原因之一,而不仅仅是. 另一个原因是你可能会忘记,甚至可能忘记)-march=native-march=haswell-mavx2 -mfma-mbmi2 -mpopcnt -mcx16-mfma


推荐阅读