2016-11-23 176 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的),如果沒有辦法讓他們根本沒有。 –

相關問題