Performance 如何正确确定英特尔处理器的-march和-mtune?

Performance 如何正确确定英特尔处理器的-march和-mtune?,performance,gcc,x86,intel,compiler-optimization,Performance,Gcc,X86,Intel,Compiler Optimization,我目前正在从对我来说性能至关重要的源代码构建一个软件。因此,我希望对其进行优化,使其能够在特定的英特尔CPU上运行。构建过程需要设置-march和-mtune标志 如果在处理器节点上使用 gcc -march=native -Q --help=target|grep march gcc -mtune=native -Q --help=target|grep mtune 我得到了3月份的core-avx2和mtune的通用版本。然而 cat /proc/cpuinfo 我得到: process

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

如果在处理器节点上使用

gcc -march=native -Q --help=target|grep march
gcc -mtune=native -Q --help=target|grep mtune
我得到了3月份的core-avx2和mtune的通用版本。然而

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:
通过访问IntelR XeonR CPU E5-2670 v3@2.30GHz的主页,我发现: 代码->产品原名haswell

如果我使用

gcc -march=haswell -Q --help=target|grep march
gcc -mtune=haswell -Q --help=target|grep mtune
我两个都很好。 那么我不应该使用haswell as march而不是core-avx2吗?最好的选择是什么

顺便说一句,我在CentOS7上使用GCC4.8.5

谢谢

编辑:

->core-avx2

gcc -mtune=native -Q --help=target | grep -- '-mtune=' | cut -f3
->一般的

顺便说一句,我在CentOS7上使用GCC4.8.5


如果性能至关重要,则应使用更新版本的GCC,并且缺少当前版本中的许多性能增强功能。当前的版本有,包括2013年不存在的许多处理器系列的-march设置。

在您使用的gcc版本中,Haswell被称为core-avx2。其他微体系结构也有蹩脚的名字。例如,常春藤桥、桑迪桥和威斯特米尔分别被称为core-avx-i、corei7 avx和corei7。从gcc 4.9.0开始,使用微体系结构的实际名称,因此在Haswell处理器上使用gcc-march=native-Q-help=target | grep-march而不是core-avx2时,gcc将打印Haswell。请参阅

当将-mtune=native传递给gcc并且您使用的gcc版本不知道主机处理器时,它将应用通用调优。您的处理器型号63仅为gcc 5.1.0所知,稍后请参阅

-Q-help=target的名称打印部分必须为-march=native选择一些名称。对于GCC无法识别的太新的CPU,如果处理器支持ADX,它将选择Broadwell之类的处理器,或者根据cpuid确定的主机处理器上支持的最高SIMD扩展至AVX2的微体系结构

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

但是对于设置调优选项,-march=native或-mtune=native完全失败,当它不能准确识别您的CPU时,会返回到generic。不幸的是,对于未知的英特尔CPU,它不执行类似于tune=intel的操作

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

编者注:否,tune=generic不适用于启用的指令集选项。它仍然是完全通用的调优,包括关心AMD Phenom或Intel Sandybridge等不支持AVX2的CPU。见和


这就是为什么应该将-march=native或-march=haswell与足够新的gcc一起使用的原因之一,而不仅仅是-mavx2-mfma。另一个原因是您可能会忘记-mbmi2-mpopcnt-mcx16,甚至可能会忘记-mfma

在x86处理器上,只需使用-march=native即可。GCC将通过将arch和tune设置为相同的值来处理其余部分。ARM更为棘手,因为在使用-march=native时,GCC有时会出现故障。你也应该使用现代的GCC或者叮当声。Clang使用一些SIMD源代码创建了比GCC更好的代码。您将需要进行基准测试,以确定哪种性能最适合您的代码。您好,感谢您的回复!不幸的是,我必须在我的本地机器上构建软件,因为在稍后使用Docker容器执行代码的集群上缺少权限,因此我没有选择native,因为它将针对我的本地机器进行优化。另外,我必须坚持GCC 4.8.5,因为很多人都在这个项目上工作,他们曾经试图升级GCC,这导致了项目中大量的不兼容。。。我想对其进行优化,使其能够在特定的英特尔CPU上运行。您可能应该更新您的问题。是的,我很抱歉,我的意思是针对我要在其上部署软件的CPU。上面列出的规范是我想要优化的目标平台的规范。它将选择支持所有
这不完全正确。-march=native部分不选择微通道并使用这些设置,它只是检查GCC知道的关于使用cpuid结果的每个CPU特性。因此,在通过CPUID选择一组奇怪的东西来公开的VM中,-march=native可能会启用AVX2,但不会启用popcnt或AES,如果CPUID报告了这一点,即使没有-march=xyz设置也可以。但是是的,对于调优设置,GCC必须专门识别处理器,如果您的CPU对GCC来说太新而无法了解,则返回到通用。有人可能会争辩说,将其识别为最新的英特尔主流CPU是可能的,而选择GCC知道的最新的此类调整,例如tune=ivybridge将更有用。或者至少-mtune=intel@petercorder是对的,但是如果处理器支持AVX2,但不支持popcnt,则gcc仍将打印Haswell。当然,在这种情况下,它不会使用popcnt。不过,这一点很好。记住这一点很重要。如果gcc不知道主机处理器的型号,我认为为旧的微体系结构(如Ivy Bridge)进行调优不是一个好主意,因为这可能会导致比在不同微体系结构(如Haswell)上进行常规调优更差的性能。你在回答中的措辞让人觉得它仍然选择了一组扩展对于特定的已知uarch。就像ADX支持会导致GCC启用AVX2一样,不管cpuid如何描述AVX2。这种猜测可能只存在于这个答案所询问的姓名打印代码中,而不存在于-march=native这个在大多数情况下都很重要的重要部分中。使用-fverbose asm并查看asm注释,以查看gcc通过启用/禁用-m选项检测到的内容。@tre95如果您知道代码将仅在支持AVX2的处理器上运行,则使用-march=core-AVX2,不需要显式-mtune=core-AVX2,因为在本例中暗示了这一点。
gcc -mtune=native -Q --help=target | grep -- '-mtune=' | cut -f3