2016-11-23 177 views
1

因此,这是我正在尝试完成的。在我的C++项目中,必须使用Microsoft Visual Studio 2015或更高版本进行编译,我需要根据用户的CPU中可用的最新SIMD指令集,有些代码具有不同版本,其中包括:SSE,SSE2,SSE3SSSE3SSE4.1SSE4.2,AVX,AVX2AVX512在Visual Studio 2015中检测要与C++宏一起使用的SIMD指令集

由于我在这里寻找的是编译时CPU调度,我的第一个猜测是,它可以很容易地使用编译器宏来完成。但是,令我惊讶的是,在VS2015中找到有关如何使用宏实现这种CPU调度的信息已经相当困难。

例如,前一个问题“Detect the availability of SSE/SSE2 instruction set in Visual Studio”有关于如何检测x86代码的SSE和SSE2的信息,但不包括x64代码的信息。虽然,他们对这个微软的文档的参考:http://msdn.microsoft.com/en-us/library/b0084kay.aspx

在那里,我们只对如何检测是否SSE,SSE2,AVX和AVX2是在编译器中启用信息 - 不正是它们是否会受到CPU支持。另外,对于其他指令集也没有任何意见,例如SSE3,SSSE3,SSE4.1,SSE4.2和AVX512。

因此,我的问题变成:我如何检测用户的CPU是否像其他编译器那样通过宏支持那些指令集,但是使用Microsoft Visual Studio 2015?

+1

除非您只打算在您编译的同一台机器上运行,否则支持的CPU功能集不是编译时常量,因此不能是宏。但是,如果你是,只要做任何MSVC等效的gcc的'-march = native',并看看像'#ifdef __AVX__'通常的目标特征宏'' –

+0

@PeterCordes但这正是问题所在。除'__AVX__'和'__AVX2__'之外没有宏。我的问题的关键在于调查人们如何实现这一目标,因为Vistual Studio似乎缺乏这样的宏。 – AndrewSteer

+0

它还应该定义'__SSE2__','__SSSE3__'等等。我不知道MSVC,但使用gcc,您可以使用'-dM'让预处理器转储所有的宏定义。 (例如'echo | gcc -march = haswell -E - -dM | less')。 '__AVX__'意味着所有英特尔SSE扩展,包括'__SSE4_2__'。不过,如果MSVC没有打算为它们定义宏,那就太奇怪了。 –

回答

2

您面临的问题是,Visual Studio历史上是用于软件供应商。你自己编译软件的想法并不在微软的DNA中。

实际结果是,微软几乎不在乎构建机的处理器。这不太可能是用来运行该软件的处理器。

另一方面,这也意味着微软不会遭受构建系统库被认为存在于目标机器上的常见Linux问题。基于Windows 10的Windows 7构建正常。例如,编译器也不允许最多启用SSE4.1。您只能使用/arch:avx或不使用任何内容。此外,该选项仅定义__AVX__,而不是gcc/clang/icc定义的常用宏,如__SSSE3__,以指示AVX隐含的先前指令集的目标支持。

+0

你能否理解OP的声明MSVC [定义'__AVX__'但不是例如'__SSSE3__'](http://stackoverflow.com/questions/40757107/detecting-simd-instruction-sets-to-be-二手与-C-宏功能于视觉工作室40759182分之2015#comment68739878_40757107)?这似乎不太可能,除非同名信息存在于命名不同的宏中。另外,我不确定这个问题是否在问这个问题,或者如何真正做到相当于'gcc -march = native'(你回答说,visual studio不支持这个)。 –

+0

@PeterCordes:不,这是正确的。有一个'__AVX__'宏,但没有'__SSSE3__'宏。这是合乎逻辑的:前者匹配'/ arch:AVX'命令行选项,但没有'/ arch:SSSE3'选项。 (有一个'/ arch:SSE2选项,但不适用于x64) – MSalters

+0

好吧,这就解释了为什么Agner Fog的矢量类库使用它自己的[INSTRSET](https://github.com/pcordes/vectorclass/blob/master/instrset。 h#L28)宏;我没有看过关于MSVC的评论。我曾希望像'__SSE3__'这样的宏是可移植的。(另外,我很惊讶,没有办法让编译器自动向量化,例如SSSE3但是不会更高,我猜编译器不会阻止你使用内在函数来指令集, t启用(如gcc/clang的),如果没有办法让他们根本没有。 –

相关问题