2016-06-10 7 views
2

SunOS 5.11 (Solaris 11.3)에서 Sun Studio 12.3에서 작업하고 있습니다. 그 나는 아주 이해가 안 컴파일 오류 제공 :ube 오류 : _mm_aeskeygenassist_si128 내장 기능이 -xarch = aes 이상 필요합니다.

-m64 추가
$ /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 

이 같은 오류가 발생합니다.

테스트 프로그램에는 별 무리가 없습니다.

$ 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 아키텍처 기능을 지정하는 방법을 배우려고 노력했습니다 : 그것은 단순히 대한 고유 SSE2, 그리고 고유 AES을 행사. 하지만 여러 사람을 지정하는 방법을 결정할 수없는 것 같습니다. 여기 내가 찾은 더 완벽한 페이지 중 하나가 있습니다 : Oracle Man Page CC.1,하지만 분명히 -xarch과 관련하여 뭔가 빠졌습니다.

내가 뭘 잘못하고 있고, 어떻게 수정합니까?

+0

'aes'는'sse2 U sse4_2'의 상위 집합이 아닙니다. 그렇다면'-xarch = aes' 옵션 만 제공하면됩니다. – Leon

+0

@ 레온 - 나는 그렇게 생각하지 않습니다. 최근 Solaris 이외의 시스템에서도 비슷한 버그 보고서를 작성했습니다. 또한 RDRAND, RDSEED 및 BMI2가 사물의 계획에 어떻게 부합되는지 파악해야하므로 문제가 나아지기 전에 문제가 더 악화 될 것입니다. – jww

+0

@ 레온 - 이전에 [맨 ​​페이지 cc.1] (http://docs.oracle.com/cd/E24457_01/html/E22003/cc.1.html) (조금 C의 것)을보고있었습니다. SSE는 자연스럽게 진행되지만 AES는 진행 과정에 포함되지 않습니다. – jww

답변

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 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 같은 인수의 확장을 오버라이드 (override) 등의 작업을 수행 할 수 있습니다.

마지막으로 또는 유일한 -xarch=... 옵션으로 -xarch=aes 플래그를 사용해야합니다.

+0

좋아, 나는 GNU의 싱글 패스 LD에 대한 경험을 토대로 그와 비슷한 것을 찾고 있었다. 다시 감사합니다. 이봐 요, 저는 Sun Studio에서 커브를 학습하는 데 너무 낮습니다 ... – jww

+0

RANDAND, RDSEED 및 BMI2는 어떻게 처리합니까? "마지막 하나"만있을 수 있습니다. 예를 들어 AES가있는 MacBook Pro는 있지만 RDRAND는 아닙니다. 나는 AES와 RDRAND가있는 Asus가 있지만 RDSEED는 아닙니다. Qtom에는 AES, RDRAND, RDSEED 및 BMI2가 있습니다. – jww

0

저는 GCC에서 온 사람들에게 대답을 던질 것입니다. SunCC는 GCC처럼하지 않습니다

가하는 등, GCC의 세계에서, 우리는 -march=native을하고 GCC는 -D__SSE2__, -D__SSE4_1__, -D__SSE4_2__, -D__AES__, -D__AVX__, -D__BMI__ 같은 매크로를 정의합니다. 그것은 __SSE2__와 같은 정의를 제공하지 않습니다. -xarch의 값도 제공하지 않습니다.

  • Solaris Studio 12.2 User's Guide
  • Solaris Studio 12.3 User's Guide
  • Solaris Studio 12.4 User's Guide (온라인 찾을 수 없습니다 PDF)

    우리가 사용할 수있는 플래그를 결정한 다음 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을 통해 컴파일러를 충돌.

    스크립트를 실행 한 결과 CFLAGSCXXFLAGS의 제조법이 제공됩니다. 아래는 4 세대 코어 i5에서 가져온 것입니다. XEON은 5 세대 Core i5와 다른 결과를 산출합니다. 예를 들어, 5 세대 코어 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 
    
    ...