Я работаю под Sun Studio 12.3 на SunOS 5.11 (Solaris 11.3). Это обеспечивает ошибку компиляции, которую я не совсем понимаю:
$ /opt/solarisstudio12.3/bin/CC -xarch=sse2 -xarch=aes -xarch=sse4_2 -c test.cxx
"test.cxx", line 11: ube: error: _mm_aeskeygenassist_si128 intrinsic requires at least -xarch=aes.
CC: ube failed for test.cxx
Добавление -m64
выдает такую же ошибку.
Там не так много для тестовой программы. Он просто использует встроенный SSE2 и встроенный AES:
$ cat test.cxx
#include <stdint.h>
#include <wmmintrin.h>
#include <emmintrin.h>
int main(int argc, char* argv[])
{
// SSE2
int64_t x[2];
__m128i y = _mm_loadu_si128((__m128i*)x);
// AES
__m128i z = _mm_aeskeygenassist_si128(y,0);
return 0;
}
Я пытался проработать руководство и узнать, как указать несколько функций архитектуры процессора, таких как SSE2, SSSE3, AES и SSE4. Но я не могу определить, как указать несколько. Вот одна из наиболее полных страниц, которые я нашел: Oracle Man Page CC.1, но я явно что-то упускаю в отношении -xarch
,
Что я делаю не так, и как мне это исправить?
Это командная строка
$ /opt/solarisstudio12.3/bin/CC -xarch=sse2 -xarch=aes -xarch=sse4_2 -c test.cxx
будет использовать последний из -xarch=sse2 -xarch=aes -xarch=sse4_2
и заставить компилятор излучать sse4_2
-совместимые двоичные файлы
Это задокументировано в Глава 3 Руководства пользователя C ++:
Некоторые общие рекомендации для параметров компилятора C ++:
Опция -llib связана с библиотекой liblib.a (или liblib.so). Всегда безопаснее ставить -lib после исходных и объектных файлов, чтобы
порядок поиска библиотек.В общем, обработка параметров компилятора осуществляется слева направо (за исключением того, что параметры -U обрабатываются после всех -D
параметры), позволяя выборочное переопределение параметров макроса (параметры, которые
включить другие варианты). Это правило не распространяется на параметры компоновщика.Опции -features, -I -l, -L, -library, -pti, -R, -staticlib, -U, -verbose и -xprefetch накапливаются, они не переопределяются.
Опция -D накапливается. Однако несколько параметров -D для одного и того же имени перекрывают друг друга.
Исходные файлы, объектные файлы и библиотеки компилируются и связываются в
порядок, в котором они появляются в командной строке.
Это сделано для того, чтобы вы могли переопределить расширение аргументов, например: -fast
, который расширяется примерно до 10 отдельных аргументов.
Вы должны использовать -xarch=aes
флаг — либо последний, либо единственный -xarch=...
вариант.
Я собираюсь бросить в ответ для тех, кто из GCC. В мире GCC мы делаем -march=native
а GCC определяет макросы как -D__SSE2__
, -D__SSE4_1__
, -D__SSE4_2__
, -D__AES__
, -D__AVX__
, -D__BMI__
, так далее.
SunCC не делает, как GCC. Это не обеспечивает определения как __SSE2__
; и при этом это не обеспечивает ценность для -xarch
,
Вот ссылки на соответствующие руководства Sun Studio и -xarch
Опции / инструкции устанавливают выбор:
Вот как мы определяем, какие флаги мы можем использовать, а затем конвертируем их в макросы препроцессора GCC. Это ужасно, но я не знаю, как получить код, сгенерированный иначе.
CC=...
EGREP=...
X86_CPU_FLAGS=$(isainfo -v 2>/dev/null)
SUNCC_510_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[0-9]|5\.[2-9]|[6-9]\.)")
SUNCC_511_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[1-9]|5\.[2-9]|[6-9]\.)")
SUNCC_512_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[2-9]|5\.[2-9]|[6-9]\.)")
SUNCC_513_OR_ABOVE=$("$CXX" -V 2>&1 | "$EGREP" -c "CC: (Sun|Studio) .* (5\.1[3-9]|5\.[2-9]|[6-9]\.)")
SUNCC_XARCH=
if [[ ("$SUNCC_511_OR_ABOVE" -ne "0") ]]; then
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE2__"); SUNCC_XARCH=sse2; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse3") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE3__"); SUNCC_XARCH=ssse3; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "ssse3") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSSE3__"); SUNCC_XARCH=ssse3; fi
if [[ ("$SUNCC_512_OR_ABOVE" -ne "0") ]]; then
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse4.1") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE4_1__"); SUNCC_XARCH=ssse4_1; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "sse4.2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__SSE4_2__"); SUNCC_XARCH=ssse4_2; fi
if [[ ("$SUNCC_513_OR_ABOVE" -ne "0") ]]; then
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "aes") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AES__"); SUNCC_XARCH=aes; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "pclmulqdq") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__PCLMUL__"); SUNCC_XARCH=aes; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "rdrand") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__RDRND__"); SUNCC_XARCH=avx_i; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "rdseed") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__RDSEED__"); SUNCC_XARCH=avx_i; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "avx") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AVX__"); SUNCC_XARCH=avx; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "avx2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__AVX2__"); SUNCC_XARCH=avx2; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "bmi") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__BMI__"); SUNCC_XARCH=avx2; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "bmi2") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__BMI2__"); SUNCC_XARCH=avx2; fi
if [[ ($(echo -n "$X86_CPU_FLAGS" | "$GREP" -c "adx") -ne "0") ]]; then PLATFORM_CXXFLAGS+=("-D__ADX__"); SUNCC_XARCH=avx2_i; fi
fi
fi
fi
fi
PLATFORM_CXXFLAGS+=("-xarch=$SUNCC_XARCH")
Приведенные выше движения позволяют нам делать такие вещи (за исключением того, что нам нужен SSE2 через ADX).
#if (_MSC_VER >= 1700) || defined(__RDRND__)
uint64_t val;
if(_rdrand64_step(&val))
{
// Use RDRAND value
}
#endif
Без вращений мы постоянно выходим из строя компиляторов с 12.1 по 12.3 во время тестирования со встроенной сборкой и встроенными функциями.
Результат запуска скрипта дает нам рецепт CFLAGS
а также CXXFLAGS
, Ниже из 4-го поколения Core i5. XEON дает разные результаты, как и Core i5 5-го поколения. Например, 5-го поколения Core i5 будет иметь ADX
и использовать -xarch=avx_i
,
Pathname: /opt/solstudio12.2/bin/CC (symlinked)
CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__ -xarch=ssse3
/opt/solarisstudio12.3/bin/CC (symlinked)
CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -xarch=ssse4_2
Pathname: /opt/solarisstudio12.4/bin/CC
CXXFLAGS: -D__SSE2__ -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__AES__ -D__PCLMUL__ -D__RDRND__ -D__AVX__ -xarch=avx
...