2

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;
}

私はマニュアルを読み、SSE2、SSSE3、AES、SSE4 などの複数の CPU アーキテクチャ機能を指定する方法を学ぼうとしています。しかし、複数のものを指定する方法を判断できないようです。これは、私が見つけたより完全なページの 1 つです: Oracle Man Page CC.1ですが、明らかに何かが欠けてい-xarchます。

私は何を間違っていますか、どうすれば修正できますか?

4

2 に答える 2

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互換性のあるバイナリを出力させます。

これは、C++ ユーザーズ ガイドの第 3 章に記載されています。

3.2 一般的なガイドライン

C++ コンパイラ オプションの一般的なガイドラインは次のとおりです。

  • -llib オプションは、ライブラリ liblib.a (または liblib.so) とリンクします。ライブラリが検索される順序を確保するために、ソース ファイルとオブジェクト ファイルの後に put-llib を使用する方が常に安全です。

  • 一般に、コンパイラ オプションの処理は左から右に行われ (ただし、-U オプションはすべて D オプションの後に処理されます)、マクロ オプション (他のオプションを含むオプション) を選択的にオーバーライドできます。この規則はリンカー オプションには適用されません。

  • -features、-I -l、-L、-library、-pti、-R、-staticlib、-U、-verbose、および -xprefetch オプションは累積され、上書きされません。

  • -D オプションが累積されます。ただし、同じ名前に複数の -D オプションを指定すると、互いにオーバーライドされます。

ソース ファイル、オブジェクト ファイル、およびライブラリは、コマンド ラインに表示される順序でコンパイルおよびリンクされます。

-fastこれは、約 10 個の個別の引数に展開されるのような引数の展開をオーバーライドするようなことができるようにするために行われます。

-xarch=aes最後に、または唯一のオプションとしてフラグを使用する必要があり-xarch=...ます。

于 2016-06-10T12:39:15.750 に答える
0

GCC から来た人たちに答えを投げかけます。GCC の世界では、GCC は、、、、などの-march=nativeマクロを定義しています。-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")

上記の回転により、このようなことが可能になります (ただし、ADX を介した SSE2 が必要です)。

#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

...
于 2016-09-11T12:35:54.940 に答える