我在Solaris 11上使用Sun Studio 12.4和12.5。我們有一個源文件,它提供了CRC32的直接C/C++實現或使用Intel內核的CRC32的優化版本。在運行時,函數指針被填充正確的實現。在預處理器中檢測-xarch選項?
使用雙至強處理器的x86服務器上的測試正在生成以下內容,因爲我們正在根據編譯器版本提供可用的代碼路徑。 SunCC 12.1增加了對SSE4的支持(如果我正確地分析了矩陣),所以我們試圖在__SUNPRO_CC >= 0x5100
時啓用它。
"crc.cpp", line 311: ube: error: _mm_crc32_u8 intrinsic requires at least -xarch=sse4_2.
SunCC確實不定義習慣GCC限定,像__SSE4_1__
和__SSE4_2__
。另外,SunCC似乎沒有像MS VC++那樣提供內部函數,編譯器版本表示支持。
SunCC似乎啓用基於-xarch
選項的功能,但它不清楚如何在預處理器中檢測它。另外,使用-xarch
會設置一些導致程序在低級處理器(如「最低」平臺)上執行失敗的位。
我有兩個問題。
- 如何檢測預處理器中的
-xarch
選項? - 如何禁用
-xarch
位,以便程序可以在低級別處理器上運行?
下面是從宏觀的轉儲-xarch=aes
編譯。注意沒有什麼可以指示可用的功能。
$ /opt/solarisstudio12.4/bin/CC -native -m64 -xarch=aes -xdumpmacros -E /dev/null 2>&1 | /usr/gnu/bin/sort --ignore-case
#1 "/dev/null"
#define __alignof__ __alignof
#define __amd64 1
#define __amd64__ 1
#define __ARRAYNEW 1
#define __asm asm
#define __asm__ asm
#define __attribute __attribute__
#define __builtin_constant_p __oracle_builtin_constant_p
#define __builtin_fpclassify __oracle_builtin_fpclassify
#define __builtin_huge_val __oracle_builtin_huge_val
#define __builtin_huge_valf __oracle_builtin_huge_valf
#define __builtin_huge_vall __oracle_builtin_huge_vall
#define __builtin_infinity __oracle_builtin_infinity
#define __builtin_isfinite __oracle_builtin_isfinite
#define __builtin_isgreater __oracle_builtin_isgreater
#define __builtin_isgreaterequal __oracle_builtin_isgreaterequal
#define __builtin_isinf __oracle_builtin_isinf
#define __builtin_isless __oracle_builtin_isless
#define __builtin_islessequal __oracle_builtin_islessequal
#define __builtin_islessgreater __oracle_builtin_islessgreater
#define __builtin_isnan __oracle_builtin_isnan
#define __builtin_isnormal __oracle_builtin_isnormal
#define __builtin_isunordered __oracle_builtin_isunordered
#define __builtin_nan __oracle_builtin_nan
#define __builtin_signbit __oracle_builtin_signbit
#define __BUILTIN_VA_STRUCT 1
#define __cplusplus 199711L
#define __DATE__ "Jul 11 2016"
#define __FILE__
#define __has_attribute(x) __oracle_has_attribute(x)
#define __has_nothrow_assign(x) __oracle_has_nothrow_assign(x)
#define __has_nothrow_constructor(x) __oracle_has_nothrow_constructor(x)
#define __has_nothrow_copy(x) __oracle_has_nothrow_copy(x)
#define __has_trivial_assign(x) __oracle_has_trivial_assign(x)
#define __has_trivial_constructor(x) __oracle_has_trivial_constructor(x)
#define __has_trivial_copy(x) __oracle_has_trivial_copy(x)
#define __has_trivial_destructor(x) __oracle_has_trivial_destructor(x)
#define __has_virtual_destructor(x) __oracle_has_virtual_destructor(x)
#define __is_abstract(x) __oracle_is_abstract(x)
#define __is_base_of(x,y) __oracle_is_base_of(x,y)
#define __is_class(x) __oracle_is_class(x)
#define __is_empty(x) __oracle_is_empty(x)
#define __is_enum(x) __oracle_is_enum(x)
#define __is_final(x) __oracle_is_final(x)
#define __is_literal_type(x) __oracle_is_literal_type(x)
#define __is_pod(x) __oracle_is_pod(x)
#define __is_polymorphic(x) __oracle_is_polymorphic(x)
#define __is_standard_layout(x) __oracle_is_standard_layout(x)
#define __is_trivial(x) __oracle_is_trivial(x)
#define __is_union(x) __oracle_is_union(x)
#define __LINE__
#define __LP64__ 1
#define __PRAGMA_REDEFINE_EXTNAME 1
#define __STDC__ 0
#define __sun 1
#define __SUN_PREFETCH 1
#define __SunOS 1
#define __SunOS_5_11 1
#define __SUNPRO_CC 0x5130
#define __SUNPRO_CC_COMPAT 5
#define __SVR4 1
#define __TIME__ "20:58:00"
#define __underlying_type(x) __oracle_underlying_type(x)
#define __unix 1
#define __volatile volatile
#define __volatile__ volatile
#define __x86_64 1
#define __x86_64__ 1
#define _BOOL 1
#define _LARGEFILE64_SOURCE 1
#define _LP64 1
#define _SIGNEDCHAR_ 1
#define _TEMPLATE_NO_EXTDEF 1
#define _WCHAR_T
#define sun 1
#define unix 1
由於約翰。我們在運行時保護我們的代碼路徑,所以我們通常只需要編譯器就可以使ASM或內部可用。也就是說,爲SSE2構建,我們可以處理其餘部分,如優化的SSE3和SSE4實現。例如,參見[crc.cpp](http://github.com/weidai11/cryptopp/blob/master/crc.cpp)和[blake2.cpp](http://github.com/weidai11/cryptopp/)斑點/主/ blake2.cpp)。 – jww
我假定你引用的守衛是像HasSSE2()和HasSSE4()這樣的函數。如果這些運行時檢查硬件功能,那麼您只需在Studio中編譯選項-Mmapfile即可。 mapfile將包含CAPABILITY條目,如「HW - = SSE2」。屏蔽在提供故障預置功能的功能最低的系統上運行所需的每個功能。 –
謝謝約翰。有太多我必須瞭解Solaris。多年來,這是一個紅頭髮的小孩,只有C/C++實現。作爲一種學習練習,我想讓它成爲一流的公民,因此它具有所有的速度優勢。 (Sun Studio 12.1及更高版本,這是第一個使用GCC內聯彙編的程序)。 – jww