[英]What's the proper way to use different versions of SSE intrinsics in GCC?
我舉一個例子來問我的問題。 現在我有一個名為do_something()
的函數。
它有三個版本: do_something()
, do_something_sse3()
和do_something_sse4()
。 當我的程序運行時,它將檢測CPU功能(看它是否支持SSE3或SSE4)並相應地調用三個版本之一。
問題是:當我用GCC構建我的程序時,我必須為do_something_sse4()
設置-msse4
來編譯(例如,要包含頭文件<smmintrin.h>
)。
但是,如果我設置-msse4
,則允許gcc使用SSE4指令, do_something_sse3()
一些內在函數也會轉換為某些SSE4指令。 因此,如果我的程序在僅支持SSE3(但沒有SSE4)的CPU上運行,則在調用do_something_sse3()
時會導致“非法指令”。
也許我有一些不好的做法。 你能提一些建議嗎? 謝謝。
我想你想建立一個所謂的“CPU調度員”。 我為GCC工作了一次(據我所知),但還沒有使用Visual Studio。
用於AVX和SSE的visual studio的cpu調度程序
我會查看Agner Fog的vectorclass和文件dispatch_example.cpp http://www.agner.org/optimize/#vectorclass
g++ -O3 -msse2 -c dispatch_example.cpp -od2.o
g++ -O3 -msse4.1 -c dispatch_example.cpp -od5.o
g++ -O3 -mavx -c dispatch_example.cpp -od8.o
g++ -O3 -msse2 instrset_detect.cpp d2.o d5.o d8.o
以下是為每個優化設置編譯單獨的目標文件的示例: http : //notabs.org/lfsr/software/index.htm
但是當使用gcc鏈接時間優化(-flto)時,即使這種方法也會失敗。 那么如何為不同的處理器完全優化構建單個可執行文件呢? 我能找到的唯一解決方案是使用include指令使C文件表現為單個編譯單元,這樣就不需要-flto。 以下是使用該方法的示例: http : //notabs.org/blcutil/index.htm
如果您在i686或x86_64計算機上使用GCC 4.9或更高版本,那么無論您的-march=XXX
和-mXXX
選項如何,您都應該能夠使用內在函數。 你可以相應地寫你的do_something()
:
void do_something()
{
byte temp[18];
if (HasSSE2())
{
const __m128i i = _mm_loadu_si128((const __m128i*)(ptr));
...
}
else if (HasSSSE3())
{
const __m128i MASK = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3);
_mm_storeu_si128(reinterpret_cast<__m128i*>(temp),
_mm_shuffle_epi8(_mm_loadu_si128((const __m128i*)(ptr)), MASK));
}
else
{
// Do the byte swap/endian reversal manually
...
}
}
你必須提供HasSSE2()
, HasSSSE3()
和朋友。 另請參閱Intrinsics for CPUID,如信息? 。
另請參閱GCC問題57202 - 請使immintrin.h之類的內在函數標題在沒有編譯器標志的情況下可用 。 但我不相信這個功能有用。 我經常遇到編譯失敗,因為GCC沒有提供內在函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.