簡體   English   中英

AVX2的gcc目標禁用SSE指令集

[英]gcc target for AVX2 disabling SSE instruction set

我們有一個我們想用AVX2編譯的翻譯單元(只有那個):它正在告訴GCC,在文件的第一行:

#pragma GCC target "arch=core-avx2,tune=core-avx2"

這曾經與GCC 4.8和4.9一起使用,但從6開始(嘗試7和8)我們得到這個警告(我們視為錯誤):

error: SSE instruction set disabled, using 387 arithmetics

在返回浮點數的第一個函數上。 我試圖像這樣啟用SSE 4.2(以及avx和avx2)

#pragma GCC target "sse4.2,arch=core-avx2,tune=core-avx2"

但這還不夠,錯誤仍然存​​在。

編輯:

相關的編譯器標志,我們針對大多數東西定位AVX:

-mfpmath=sse,387 -march=corei7-avx -mtune=corei7-avx

EDIT2:最小樣本:

#pragma GCC target "arch=core-avx2,tune=core-avx2"

#include <immintrin.h>
#include <math.h>

static inline float
lg1pf( float x ) {
    return log1pf(x)*1.44269504088896338700465f;
}

int main()
{
  log1pf(2.0f);
}

編譯方式:

gcc -o test test.c -O2 -Wall -Werror -pedantic -std=c99 -mfpmath=sse,387 -march=corei7-avx -mtune=corei7-avx

In file included from /home/xxx/gcc-7.1.0/lib/gcc/x86_64-pc-linux-gnu/7.1.0/include/immintrin.h:45:0,
                 from test.c:3:
/home/xxx/gcc-7.1.0/lib/gcc/x86_64-pc-linux-gnu/7.1.0/include/avx512fintrin.h: In function ‘_mm_add_round_sd’:
/home/xxx/gcc-7.1.0/lib/gcc/x86_64-pc-linux-gnu/7.1.0/include/avx512fintrin.h:1412:1: error: SSE register return with SSE disabled
 {
 ^

GCC詳細信息(我沒有用於編譯它的標志)gcc --version gcc(GCC)7.1.0版權所有(C)2017 Free Software Foundation,Inc。這是免費軟件; 查看復制條件的來源。 沒有保修; 甚至不適用於適銷性或特定用途的適用性。

潛在解決方案

#pragma GCC target "avx2"

在沒有對代碼進行其他更改的情況下為我工作。 將屬性應用於單個函數也不起作用:

相關問題:

__attribute__((__target__("arch=broadwell")))  // does not compile
__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }

__attribute__((__target__("avx2,arch=broadwell"))) // does not compile
__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }

__attribute__((__target__("avx2"))) // compiles
__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }

這看起來像一個bug。 #pragma GCC target #include <immintrin.h>之前的#pragma GCC target以某種方式打破了標題,IDK為什么。 即使在-march=haswell的命令行上啟用了AVX2,#pragma似乎-march=haswell破壞之后定義的任何內在函數的內聯。

您可以在標頭之后使用#pragma ,但是然后使用未在命令行上啟用的instrinsics會失敗。

即使像#pragma GCC target "arch=haswell"這樣的更現代的目標名稱#pragma GCC target "arch=haswell"導致錯誤,所以並不是像corei7-avx這樣古老的模糊目標名稱一般都會被破壞。 他們仍然在命令行上工作。 如果要為整個文件啟用某些內容,標准方法是使用編譯器選項而不是編譯指示。

盡管如此,GCC確實聲稱支持基於pragma或__attribute__的每個功能的目標選項。 https://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html


這就是我已經開始玩這個了( 帶有gcc8.1的Godbolt編譯器瀏覽器 )。 Clang不受影響,因為它忽略了#pragma GCC target (這意味着#pragma不是非常便攜;你可能希望你的代碼適用於任何GNU C編譯器,而不僅僅是gcc本身。)

 // breaks gcc when before immintrin.h
 // #pragma GCC target "arch=haswell"

#include <immintrin.h>
#include <math.h>

//#pragma GCC target "arch=core-avx2,tune=core-avx2"
#pragma GCC target "arch=haswell"

//static inline 
float
lg1pf( float x ) {
    return log1pf(x)*1.44269504088896338700465f;
}

// can accept / return wide vectors
__m128 nop(__m128 a) { return a; }
__m256 require_avx(__m256 a) { return a; }
// but error on using intrinsics if #include happened without target options
//__m256 use_avx(__m256 a) { return _mm256_add_ps(a,a); }

// this works, though, because AVX is enabled at this point
// presumably so would  __builtin_ia32_whatever
// Without `arch=haswell`, this breaks, so we know the pragma "worked"
__m256 use_native_vec(__m256 a) { return a+a; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM