我在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
相关的内容。
我做错了什么,我该如何解决?
答案 0 :(得分:3)
此命令行
$ /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一般准则
C ++编译器选项的一些通用指南是:
-llib选项链接库liblib.a(或liblib.so)。在源文件和目标文件之后放置llib总是更安全 搜索库的顺序。
一般情况下,编译器选项的处理是从左到右(除了在所有D之后处理-U选项) 选项),允许选择性覆盖宏选项(选项) 包括其他选项)。此规则不适用于链接器选项。
-features,-I -l,-L,-library,-pti,-R,-staticlib,-U,-verbose和-xprefetch选项会累积,它们不会覆盖。
-D选项累积。但是,同名的多个-D选项会相互覆盖。
编译和链接源文件,目标文件和库 它们在命令行中出现的顺序。
这样做就可以完成覆盖-fast
, which expands to about 10 separate arguments等参数扩展的事情。
您应该使用-xarch=aes
标记 - 最后一个或仅作为-xarch=...
选项。
答案 1 :(得分:0)
我打算回答那些来自海湾合作委员会的人。在海湾合作委员会的世界中,我们-march=native
和GCC定义了像-D__SSE2__
,-D__SSE4_1__
,-D__SSE4_2__
,-D__AES__
,-D__AVX__
,{{1}这样的宏等等。
SunCC不像GCC那样做。它不提供像-D__BMI__
这样的定义;它也没有为__SSE2__
提供价值。
以下是相关Sun Studio手册和-xarch
选项/说明集选项的参考:
以下是我们如何确定可以使用的标志,然后将它们转换为GCC预处理器宏。它很糟糕,但我不知道如何获得生成的代码。
-xarch
上面的回转允许我们做这样的事情(除了我们需要SSE2虽然是ADX)。
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")
如果没有这些旋转,我们会在测试期间使用内联汇编和内在函数不断地使12.1到12.3编译器崩溃。
运行脚本的结果为我们提供了#if (_MSC_VER >= 1700) || defined(__RDRND__)
uint64_t val;
if(_rdrand64_step(&val))
{
// Use RDRAND value
}
#endif
和CFLAGS
的配方。以下是第4代Core i5。 XEON产生不同的结果,第五代Core i5也是如此。例如,第5代Core i5将CXXFLAGS
并使用ADX
。
-xarch=avx_i