2014-12-10 30 views
6

如果我們查詢:-march=native擴展到,結果似乎理所應當的爲什麼`gcc -Q -march = corei7-avx --help = target`謊言?

$ gcc -Q -march=native --help=target | grep -E '^\s+-.*(sse|march)' 
    -march=       corei7-avx 
    -mno-sse4       [disabled] 
    -msse        [enabled] 
    -msse2       [enabled] 
    -msse2avx       [disabled] 
    -msse3       [enabled] 
    -msse4       [enabled] 
    -msse4.1       [enabled] 
    -msse4.2       [enabled] 
    -msse4a       [disabled] 
    -msse5        
    -msseregparm      [disabled] 
    -mssse3       [enabled] 

但如果是直接指定的架構,GCC下降上證所標誌,將啓用native,爲什麼呢?

$ gcc -Q -march=corei7-avx --help=target | grep -E '^\s+-.*sse' 
    -mno-sse4       [enabled] 
    -msse        [disabled] 
    -msse2       [disabled] 
    -msse2avx       [disabled] 
    -msse3       [disabled] 
    -msse4       [disabled] 
    -msse4.1       [disabled] 
    -msse4.2       [disabled] 
    -msse4a       [disabled] 
    -msse5        
    -msseregparm      [disabled] 
    -mssse3       [disabled] 

然而,編譯與-march=corei7-avx表明,它們將被啓用。

$ echo | gcc -march=corei7-avx -dM -E - | grep -i sse 
#define __SSE4_1__ 1 
#define __SSE4_2__ 1 
#define __SSE2_MATH__ 1 
#define __SSE_MATH__ 1 
#define __SSE2__ 1 
#define __SSSE3__ 1 
#define __SSE__ 1 
#define __SSE3__ 1 
+2

Lie意味着欺騙的意圖,我懷疑是這種情況,使用*不正確*或其他類似的詞似乎更合適。 – 2014-12-11 02:47:28

回答

3

我猜了一點,但無論如何,這是一個解說太久......

看看這個命令的輸出:

$ echo | gcc -march=native -v -x c -c - 

這等:

$ echo | gcc -march=corei7-avx -v -x c -c - 

有趣的部分是在調用cc1二進制文件。在-march=native的情況下,它被所有的目標選項取代,而不僅僅是等效的-march之一。我有一個sandybridge,所以在我的機器上它給:

.../cc1 -march=sandybridge -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 \ 
     -mno-sse4a -mcx16 -msahf -mno-movbe -mno-aes -mno-sha -mpclmul \ 
     -mpopcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop ... 

當您添加(在我的情況-march=sandybridge)的-march=corei7-avx或有沒有這些具體架構的選項而。

現在,我的結論是:

-Q --help=target輸出告訴給編譯器選項是否設置,如果沒有功能實際上是啓用。正如所發生的那樣,這些功能中的一些功能可以通過不同的方式啓用或禁用。

例如,SSE可以使用-msse,也可以使用-march=corei7-avx-march=sandybridge。但是,儘管指定-march=corei7-avx啓用SSE,但它並沒有設置選項本身

在另一方面-march=native設置了很多的選擇,不僅實際-march也可以從運行系統中獲取,如緩存大小任何其他相關選項。

正如您已經注意到的那樣,檢查特定功能開啓還是關閉的正確方法是檢查預定義的defines

3

這是GCC (39851)中的一個已知錯誤;它已於2009年GCC4.5以來開放。