ube error: _mm_aeskeygenassist_si128 intrinsic requires at least -xarch=aes
ube error: _mm_aeskeygenassist_si128 intrinsic requires at least -xarch=aes
我在 SunOS 5.11 (Solaris 11.3) 上的 Sun Studio 12.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;
}
我一直在尝试阅读手册并了解如何指定多个 cpu 架构功能,例如 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
兼容的二进制文件。
这在 Chapter 3 of the C++ User's Guide 中有记录:
3.2 General Guidelines
Some general guidelines for the C++ compiler options are:
The-llib option links with library liblib.a (or liblib.so). It is always safer to put-llib after the source and object files to ensure
the order in which libraries are searched.
In general, processing of the compiler options is from left to right (with the exception that-U options are processed after all-D
options), allowing selective overriding of macro options (options that
include other options). This rule does not apply to linker options.
The -features, -I -l, -L, -library, -pti, -R, -staticlib, -U, -verbose, and -xprefetch options accumulate, they do not override.
The -D option accumulates. However, multiple -D options for the same name override each other.
Source files, object files, and libraries are compiled and linked in
the order in which they appear on the command line.
这样做是为了让您可以做一些事情,例如覆盖 -fast
, which expands to about 10 separate arguments.
等参数的扩展
您应该使用 -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
options/instructions 设置选项的参考:
- Sun Studio 12 Update 1 User's Guide(PDF;无法在线找到)
- Solaris Studio 12.2 User's Guide
- Solaris Studio 12.3 User's Guide
- Solaris Studio 12.4 User's Guide
- Developer Studio 12.5 User's Guide
以下是我们如何确定可以使用哪些标志,然后将它们转换为 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 though 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 和第 5 代 Core i5 产生不同的结果。例如,第 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
...
我在 SunOS 5.11 (Solaris 11.3) 上的 Sun Studio 12.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;
}
我一直在尝试阅读手册并了解如何指定多个 cpu 架构功能,例如 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
兼容的二进制文件。
这在 Chapter 3 of the C++ User's Guide 中有记录:
3.2 General Guidelines
Some general guidelines for the C++ compiler options are:
The-llib option links with library liblib.a (or liblib.so). It is always safer to put-llib after the source and object files to ensure the order in which libraries are searched.
In general, processing of the compiler options is from left to right (with the exception that-U options are processed after all-D options), allowing selective overriding of macro options (options that include other options). This rule does not apply to linker options.
The -features, -I -l, -L, -library, -pti, -R, -staticlib, -U, -verbose, and -xprefetch options accumulate, they do not override.
The -D option accumulates. However, multiple -D options for the same name override each other.
Source files, object files, and libraries are compiled and linked in the order in which they appear on the command line.
这样做是为了让您可以做一些事情,例如覆盖 -fast
, which expands to about 10 separate arguments.
您应该使用 -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
options/instructions 设置选项的参考:
- Sun Studio 12 Update 1 User's Guide(PDF;无法在线找到)
- Solaris Studio 12.2 User's Guide
- Solaris Studio 12.3 User's Guide
- Solaris Studio 12.4 User's Guide
- Developer Studio 12.5 User's Guide
以下是我们如何确定可以使用哪些标志,然后将它们转换为 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 though 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 和第 5 代 Core i5 产生不同的结果。例如,第 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
...