SlideShare a Scribd company logo
1 of 53
SSE 병렬 프로그래밍


       데브루키
     돼지고기(구경원)
SIMD.

 • Single Instruction Multiple Data
 • CPU에서 지원하는 일종의 명령어 셋.
 • 한번의 연산으로 다수의 데이터를 처리할
   수 있다.

 •   SISD - Single Instruction Single Data
 •   SIMD - Single Instruction Multiple Data
 •   MISD - Multiple Instruction Single Data
 •   MIMD - Multiple Instruction Multiple Data
SIMD.

        Input Data               Output Data




                     SISD 명령어
        Input Data               Output Data




                     SIM D 명령어
SIMD.

 • SISD
  …   …   11   10   v      8      7         6     5       4         3   2   1




 • SIMD                 연산의 방향
                         32 bit       32 bit     32 bit       32 bit
  4   3   2    1           4            3             2         1
                           +            +             +         +
  8   7   6    5           8            7             6         5
                           +            +             +         +
                          12           11         10            9
                           +            +             +         +
                          16           15         14           13
                           =            =             =         =
                          40           36         32           28


                                                4값의 합 = 136
SIMD 구현 방법.

 • 어셈블리 SIMD 명령어
 • Intrinsic 함수
 • Vector Class

   SIMD 명령어   Intrinsic 함수   Vector Class


     xmm0       __m128i        Is16vec8


     xmm1       __m128       Is32vec4 ~

      ~         __m128d        F32vec4

     xmm7                      F64vec2
SIMD 구현 방법.
SIMD 구현 조건.

 •   프로젝트의 중요 부분 또는 병목 지점인가.
 •   SIMD 구조에 적합한가.
 •   성능향상에 도움이 되어지는가.
 •   정수형, 실수형 인지 파악.
 •   128bit에 담을 수 있는 데이터 개수 고려.
 •   제작기간, 디버깅 테스트 기간 고려.
 •   구현 도구 결정.
 •   SISD와 SIMD 성능 비교 테스트.
SSE.

 •   Streaming SIMD Extensions
 •   XMM 128비트 레지스터 8개가 존재.
 •   인텔이 1999년 펜티엄3 프로세서에 도입.
 •   FLOAT, POINT. 비교로직 등 다양한 연산
     가능.
        Packing 사이즈    byte   short    integer
        병렬 연산 개수        16      8         4
      C 코드와 성능 차이     4~6배     2배     10~30%
CPU 구현 프로세서.
IA-32 / 64 레지스터
SIMD 연산 타입

                 32 bit A3      32 bit A2     32 bit A1     32 bit A0
 Scalar 덧셈 계산                                                  +
                  32 bit B3     32 bit B2     32 bit B1     32 bit B0
                                                               =
                 32 bit A3      32 bit A2     32 bit A1   32 bit A0+ B0



                 32 bit A3      32 bit A2     32 bit A1     32 bit A0
 Packed 덧셈 계산        +             +             +             +
                  32 bit B3     32 bit B2     32 bit B1     32 bit B0
                     =             =             =             =
                32 bit A3+ B3 32 bit A2+ B2 32 bit A1+ B1 32 bit A0+ B0
중요 어셈블리

•   mov
•   add / sub
•   mul / div
•   inc / dec
• shl / shr
• cmp / jp
어셈블리 예제.

  __asm
     {
          pushad
          mov eax, A
          mov ebx, B
          add eax, ebx
          mov C, eax
          popad
    }
어셈블리 예제.

  __asm
     {
          pushad
          mov ebx, 15
          mov eax, A
          mul ebx
          mov C, eax
          popad
    }
어셈블리 예제.
  __asm
      {
          pushad

          mov eax, 17
          cdq            //32 bit를 64 bit로 확장
          //convert double word to quad word

          mov ebx, A
          div ebx
          mov B, eax

          mov C, edx

          popad
    }
어셈블리 예제.
  __asm
      {
          pushad

          mov eax, 0
  LOOP:

          //필요한 연산

          inc eax
          cmp eax, 1000
          jne LOOP

          mov nValue, eax
          popad
    }
SIMD 명령어
• 정수형과 실수형 두 가지 병렬 연산 방식이 있다.
• Pack 형식에 따라 연산 방식이 달라짂다.
• MMX 에서는 64bit 병렬 연산만 가능했지만 SSE
  로 넘어오면서 128bit 병렬 연산이 가능해졌다.
• 구현코드가 CPU에서 똑같이 동작한다.
• 디버깅이 어렵고, 가독성이 앆좋다.
명명법

P <SIMD_op> <suffix>
접미사      원어        사이즈                        의 미

 S      signed       -      양수값을 의미하는 접미사로 사이즈를 의미하는 단어 앞에 오게 된다.

 U     unsigned      -              +- 부호를 갖는 데이터형임을 의미한다.

 B       Byte      8 bit        해당 데이터는 8 bit 정수 형 16개를 연산할 수 있다.

 W      Word       16 bit       해당 데이터는 16 bit 정수 형 8개를 연산할 수 있다.

 D    DoubleWord   32 bit       해당 데이터는 32 bit 정수 형 4개를 연산할 수 있다.

 Q    QuadWord     64 bit       해당 데이터는 64 bit 정수 형 2개를 연산할 수 있다.
메모리 align, unalign

• 정렬된 메모리를 사용하는 것이 빠르다.

• 정렬된 메모리
• __declspec( align(16) ) int array[100];

• 정렬되지 않은 메모리
• Int array[100]
MOVDQU
    Move Unaligned Double Quad word

  • 128bit 레지스트 또는 128bit 메모리에 정
    렬되지 않은 값을 읽어올 때 사용한다

                                     16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit
          16 Byte Unaligned Memory     8        7        6        5        4        3        2        1


M OVDQU                              16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit
          xmm0 레지스터                    8        7        6        5        4        3        2        1
MOVDQA
          Move aligned Double Quad word

  • 128bit 레지스터 또는 128bit 메모리에 정렬되어
    있는 값을 읽어올 때 사용 한다.
  • 메모리가 정렬되어 있기 때문에 읽어오는 속도
    가 빠르다.


                                   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit
          16 Byte Aligned Memory     8        7        6        5        4        3        2        1


M OVDQA                            16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit   16 bit
          xmm0 레지스터                  8        7        6        5        4        3        2        1
논리연산

          32 bit    32 bit   32 bit   32 bit
SourceA     1         1        0        0


SourceB     1         0        1        0


PAND        1         0        0        0


 POR        1         1        1        0


 PXOR       0         1        1        0


PANDN       0         0        1        0
PADDD
                (Packed Add)

• 더하기 연산을 한다


                32 bit   32 bit   32 bit   32 bit
         xmm0     4        3        2        1
 paddd            +        +        +        +
         xmm1     8        7        6        5
                  =        =        =        =
         xmm0    12       10        8        6
PADDD
              (Packed Add)
int IntArrayA[4] = { 1,2,3,4 };
int IntArrayB[4] = { 5,6,7,8 };
int IntResult[4] = {0};

__asm
{
        pushad

        movdqu xmm0, IntArrayA
        movdqu xmm1, IntArrayB
        paddd xmm0, xmm1
        movdqu IntResult, xmm0

        popad
        emms
}
PADDD
                   (Packed Add)

• SISD
 …   …   11   10   v      8      7         6     5       4         3   2   1




• SIMD                 연산의 방향
                        32 bit       32 bit     32 bit       32 bit
 4   3   2    1           4            3             2         1
                          +            +             +         +
 8   7   6    5           8            7             6         5
                          +            +             +         +
                         12           11         10            9
                          +            +             +         +
                         16           15         14           13
                          =            =             =         =
                         40           36         32           28


                                               4값의 합 = 136
최대값 구하기

short GetMaxValueC(const short *pShortArray,const int nSize)
{
    short MaxValue = 0;
    for(int i = 0; i< nSize ; i++)
    {
            if(pShortArray[i] > MaxValue )
                    MaxValue = pShortArray[i];

    }
    return MaxValue;
}
최대값 구하기
const short* pShort = pShortArray;
//스택포인터변수로받아온다.

int nLoopCount = (nSize / 8)*16;
//8배수개수를한번에계산

int nRemain = nSize % 8;
//8배수나머지영역은C로구현

short nMaxValue = 0;
//결과값을가지고있을메모리변수
최대값 구하기
•   __asm
•   {
•             pushad
•             mov eax, pShort

•             mov esi, 0
•
•             mov ecx, nLoopCount
•             pxor xmm1, xmm1
•   FINDLP:
•             movdqu xmm0, [eax+esi]       .

•             pmaxsw xmm1, xmm0
•
•             add esi, 16                  .
•             cmp esi, ecx
•             jne FINDLP

•             movdqu MaxValueArray, xmm1
•             popad
•             emms
•   }
최대값 구하기
•   for( unsigned char Count = 0; Count < 8 ; Count++)
•   {
•            if( MaxValueArray[Count] > nMaxValue )
•                     nMaxValue = MaxValueArray[Count];
•   }
•
•   if( nRemain != 0)
•   {
•           for( int i = nSize-nRemain; i< nSize; i++)
•           {
•                      if(pShortArray[i] > nMaxValue )
•                               nMaxValue = pShortArray[i];
•           }
•   }
GetLength()
                   f = sqrtf(x_ * x_ + y_ * y_ + z_ * z_);

•   FLOAT*    p = &f;   w_ = 0.0f;
• __asm {
      –   mov ecx, p
      –   mov esi, this
      –   movups xmm0, [esi]
      –   mulps xmm0, xmm0
      –   movaps xmm1, xmm0
      –   shufps xmm1, xmm1, 01001110b
      –   addps xmm0, xmm1
      –   movaps xmm1, xmm0
      –   shufps xmm1, xmm1, 00010001b
      –   addps xmm0, xmm1
      –   sqrtss xmm0, xmm0
      –   movss [ecx], xmm0
• }
최대값 구하기
Intrinsic 함수

• 코드의 분석이 쉽다.
• SIMD 명령어를 inline 함수로 구현하여, 함수의
  성능은 SIMD 명령어 셋과 차이가 별로 없다.
• Scalar 형 intrinsic 함수는 어셈블리 SIMD 명령
  어 보다 약간의 성능저하가 있을 수 있다.
• SIMD 명령어 보다 코드 작성에 편리하다.
명명법

_mm_<intrin_op>_<suffix>

문자                                    데이터 타입
 s     32bit 실수형 (single-precision floating point)
 d     64bit 실수형 (double-precision floating point)
i128   128bit signed 정수 (signed 128-bit integer)
i64    64bit signed 정수 (signed 64-bit integer)
u64    64bit unsigned 정수 (unsigned 64-bit integer)
i32    32bit signed 정수 (signed 32-bit integer)
u32    32bit unsigned 정수 (unsigned 32-bit integer)
i16    16bit signed 정수 (signed 16-bit integer)
u16    16bit unsigned 정수 (unsigned 16-bit integer)
 i8    8bit signed 정수 (signed 8-bit integer)
u8     8bit unsigned 정수 (unsigned 8-bit integer)
Intrinsic 함수

• 헤더 파일 include
• - #include <xmmintrin.h> SSE
  - #include <emmintrin.h> SSE2
  - #include <pmmintrin.h> SSE3
  - #include <smmintrin.h> <nmmintrin.h> SSE4
__m128 자료형

• SIMD 연산을 위한 자료형으로 XMM 레지스트와
  1대 1 대응되는 구조체이다.

 ___m128i   32 bit integer   32 bit integer   32 bit integer   32 bit integer
Intrinsic LOAD. STORE

__m128i r = _mm_load_si128(__m128i const *p)
                           16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit
 16Byte Align Memory p      p[7]     p[6]    p[5]     p[4]   p[3]   p[2]   p[1]   p[0]



        __m128i r           r[7]     r[6]    r[5]     r[4]   r[3]   r[2]   r[1]    r[0]



void _mm_st ore_si128(__m128i *p, __m128i b)
                             16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit
         __m128i b            b[7]    b[6]     b[5]   b[4]   b[3]   b[2]   b[1]   b[0]



   16Byte Align Memory p      p[7]    p[6]     p[5]   p[4]   p[3]   p[2]   p[1]   p[0]
Intrinsic 함수


short Source[8] = {1,2,3,4,5,6,7,8};
short Dest[8] = {0};

__m128i xmm0 = _mm_loadu_si128((__m128i*)Source);
__m128i xmm1 = xmm0;

_mm_storeu_si128((__m128i*)Dest, xmm1);
Intrinsic ADD. SUB

__m128i R = _mm_add_epi16(__m128i a, __m128i b)
  __m128i a      a7       a6       a5       a4       a3      a2      a1      a0

                 +        +        +        +        +       +       +       +

  __m128i b      b7       b6       b5       b4       b3      b2      b1      b0

                 =        =        =        =        =       =       =       =

  __m128i r     a7+b7    a6+b6    a5+b5    a4+b4    a3+b3   a2+b2   a1+b1   a0+b0



__m128i R = _mm_sub_epi16(__m128i a, __m128i b)
   __m128i a      a7       a6       a5       a4       a3      a2     a1      a0

                     -        -        -      -       -       -       -       -

  __m128i b       b7       b6       b5       b4       b3     b2      b1      b0

                     =      =       =        =        =       =       =      =

   __m128i r     a7-b7    a6-b6    a5-b5    a4-b4   a3-b3   a2-b2   a1-b1   a0-b0
Intrinsic MUL


__m128i R = _mm_mullo_epi16(__m128i a, __m128i b)
  __m128i a    a7      a6      a5      a4      a3      a2      a1      a0

                *       *       *       *       *       *       *       *

 __m128i b     b7      b6      b5      b4      b3      b2      b1      b0

               =       =       =       =       =       =       =       =

  __m128i r   a7*b7   a6*b6   a5*b5   a4*b4   a3*b3   a2*b2   a1*b1   a0*b0
Intrinsic MAX. MIN
__m128i R = _mm_max_epi16(__m128i a, __m128i b)

 __m128i a       a7           a6           a5           a4            a3           a2           a1            a0

                max          max          max           max          max          max          max            max

 __m128i b       b7           b6           b5           b4            b3           b2           b1            b0

                  =            =            =            =            =            =             =             =

 __m128i r    max(a7,b7)   max(a6,b6)   max(a5,b5)   max(a4,b4)   max(a3,b3)   max(a2,b2)    max(a1,b1)    max(a0,b0)



__m128i R = _mm_min_epi16(__m128i a, __m128i b)
  __m128i a       a7           a6           a5          a4           a3           a2            a1           a0

                  min         min          min          min          min          min          min           min

 __m128i b        b7           b6           b5          b4           b3           b2           b1            b0

                   =           =            =            =            =            =            =             =

  __m128i r   min(a7,b7)   min(a6,b6)   min(a5,b5)   min(a4,b4)   min(a3,b3)   min(a2,b2)   min(a1,b1)    min(a0,b0)
최대값 구하기
const short* pShort = pShortArray;
int nRemain = nSize % 8;
short nMaxValue = 0;
short MaxValueArray[8] ={0};

__m128i XMMCurrentValue;
__m128i XMMMaxValue;

for(unsigned int Index =0 ; Index < nSize; Index+=8)
{
         XMMCurrentValue = _mm_loadu_si128((__m128i*)(pShortArray+Index));
                  //16byte 씩읽어온다.

        XMMMaxValue = _mm_max_epi16(XMMMaxValue, XMMCurrentValue);
             //16byte 씩더한다.
}
최대값 구하기
Vector 클래스
• Intrinsic 데이터형 또는 함수를 클래스화시
  킨 라이브러리.
• Intrinsic 를 이용할 때 보다 직관적이고 사
  용이 편리하다.
• 연산자 오버로딩으로 만들어져 있다.
Vector 클래스

• 명명법
 – <type><signedness><bits>vec<elements>

 Iu32vec4
 32bit unsigned int 형 정수를 4개 담고 있는 vector 클래스.

 Fs16vec8
 8bit signed short 형 실수를 8개 담고 있는 vector 클래스.
Vector 클래스
 class        부호          pack 데이터 타입   pack 사이즈   pack 개수   해더 파일

I128vec1   unspecified      __m128i       128         1      dvec.h

I64vec2    unspecified       __int64       64         2      dvec.h

Is64vec2     signed          __int64       64         2      dvec.h

Iu64vec2    unsigned         __int64       64         2      dvec.h

I32vec4    unspecified         int         32         4      dvec.h

Is32vec4     signed            int         32         4      dvec.h

Iu32vec4    unsigned           int         32         4      dvec.h

I16vec8    unspecified       short         16         8      dvec.h

Is16vec8     signed          short         16         8      dvec.h

Iu16vec8    unsigned         short         16         8      dvec.h

I8vec16    unspecified        char         8         16      dvec.h

Is8vec16     signed           char         8         16      dvec.h

Iu8vec16    unsigned          char         8         16      dvec.h
Vector 클래스
__asm{
movaps xmm0, a
movaps xmm1, b
addps xmm0, xmm1
movaps c, xmm0
}


                    #include < xmmintrin.h >
                    __m128 a, b, c;
                    c = _mm_add_ps( a, b);

#include <fvec.h>
F32vec4 A, B, C
C = A + B;
Vector 클래스 읽고. 쓰기
    __declspec(align(16)) short A[8] = {1,2,3,4,5,6,7,8};
    __declspec(align(16)) short R[8] = {0};

    Is16vec8 Vector(1,2,3,4,5,6,7,8);           //역순으로 8부터 입력

    _mm_store_si128((__m128i *)R, Vector);      //intrinsic 함수로 쓰기

    printf("Store : %d, %d, %d, %d, %d, %d, %d, %dn"
             ,R[0],R[1],R[2],R[3],R[4],R[5],R[6],R[7]);

    Is16vec8 *a = (Is16vec8 *)A;                //포인터 캐스팅으로 바로 읽
기

    Is16vec8 *r = (Is16vec8 *)R;

    *r = *a;         //대입 연산

    printf("Store : %d, %d, %d, %d, %d, %d, %d, %dn"
             ,R[0],R[1],R[2],R[3],R[4],R[5],R[6],R[7]);
    return 0;
Vector 클래스 사칙연산

Is16vec8 A;
Is16vec8 B;
Is16vec8 R;
R = A + B;              //덧셈 연산
R += A;
R = A - B;              //뺄셈 연산
R -= A;
R = A * B;              //곱셈 연산
R *= A;
R = mul_high( A, B );   //곱셈 상위 bit
R = mul_add( A, B);     //곱 합 연산
최대값 구하기

const short* pShort = pShortArray;
int nRemain = nSize % 8;
short nMaxValue = 0;
short MaxValueArray[8] ={0};

Is16vec8* XMMCurrentValue;
Is16vec8 XMMMaxValue;

for(unsigned int Index =0 ; Index < nSize; Index+=8)
{
         XMMCurrentValue = (Is16vec8*)(pShortArray+Index);
         XMMMaxValue = simd_max(XMMMaxValue,* XMMCurrentValue);
}
최대값 구하기
마무리

- SSE를 사용하면 C/C++ 보다 빠른 성능 향상을 볼 수 있
  다.
- 멀티코어 시대에 SSE의 사용은 미래를 대비하는 일이다.
- 아직까지 가독성의 문제가 남아있다.
- 반복되는 계산량이 많은 부분에서 많은 이득을 볼 수
  있다.
- 캐쉬라인 정렬이 되어있어야 효율적이다.
Q&A
END

More Related Content

What's hot

LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会NVIDIA Japan
 
Spectre/Meltdownとその派生
Spectre/Meltdownとその派生Spectre/Meltdownとその派生
Spectre/Meltdownとその派生MITSUNARI Shigeo
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるAtsushi KOMIYA
 
Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)
Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)
Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)MITSUNARI Shigeo
 
LLVM Register Allocation
LLVM Register AllocationLLVM Register Allocation
LLVM Register AllocationWang Hsiangkai
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ SEGADevTech
 
Tcache Exploitation
Tcache ExploitationTcache Exploitation
Tcache ExploitationAngel Boy
 
LLVM Backend の紹介
LLVM Backend の紹介LLVM Backend の紹介
LLVM Backend の紹介Akira Maruoka
 
20111015 勉強会 (PCIe / SR-IOV)
20111015 勉強会 (PCIe / SR-IOV)20111015 勉強会 (PCIe / SR-IOV)
20111015 勉強会 (PCIe / SR-IOV)Kentaro Ebisawa
 
LLVM Backend Porting
LLVM Backend PortingLLVM Backend Porting
LLVM Backend PortingShiva Chen
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門Fixstars Corporation
 
Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)Angel Boy
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
Low-level Shader Optimization for Next-Gen and DX11 by Emil Persson
Low-level Shader Optimization for Next-Gen and DX11 by Emil PerssonLow-level Shader Optimization for Next-Gen and DX11 by Emil Persson
Low-level Shader Optimization for Next-Gen and DX11 by Emil PerssonAMD Developer Central
 

What's hot (20)

LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会
 
Boost.SIMD
Boost.SIMDBoost.SIMD
Boost.SIMD
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
Spectre/Meltdownとその派生
Spectre/Meltdownとその派生Spectre/Meltdownとその派生
Spectre/Meltdownとその派生
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
 
Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)
Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)
Xeon PhiとN体計算コーディング x86/x64最適化勉強会6(@k_nitadoriさんの代理アップ)
 
llvm入門
llvm入門llvm入門
llvm入門
 
LLVM Register Allocation
LLVM Register AllocationLLVM Register Allocation
LLVM Register Allocation
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
 
Tcache Exploitation
Tcache ExploitationTcache Exploitation
Tcache Exploitation
 
LLVM Backend の紹介
LLVM Backend の紹介LLVM Backend の紹介
LLVM Backend の紹介
 
20111015 勉強会 (PCIe / SR-IOV)
20111015 勉強会 (PCIe / SR-IOV)20111015 勉強会 (PCIe / SR-IOV)
20111015 勉強会 (PCIe / SR-IOV)
 
LLVM Backend Porting
LLVM Backend PortingLLVM Backend Porting
LLVM Backend Porting
 
Binary Reading in C#
Binary Reading in C#Binary Reading in C#
Binary Reading in C#
 
Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)Windows 10 Nt Heap Exploitation (English version)
Windows 10 Nt Heap Exploitation (English version)
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Low-level Shader Optimization for Next-Gen and DX11 by Emil Persson
Low-level Shader Optimization for Next-Gen and DX11 by Emil PerssonLow-level Shader Optimization for Next-Gen and DX11 by Emil Persson
Low-level Shader Optimization for Next-Gen and DX11 by Emil Persson
 

Viewers also liked

병렬 프로그래밍 패러다임
병렬 프로그래밍 패러다임병렬 프로그래밍 패러다임
병렬 프로그래밍 패러다임codenavy
 
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기zupet
 
병렬 프로그래밍
병렬 프로그래밍병렬 프로그래밍
병렬 프로그래밍준혁 이
 
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기Kiheon Park
 
병렬프로그래밍과 Cuda
병렬프로그래밍과 Cuda병렬프로그래밍과 Cuda
병렬프로그래밍과 CudaSeok-joon Yun
 
빌드 속도를 올려보자
빌드 속도를 올려보자빌드 속도를 올려보자
빌드 속도를 올려보자KyeongWon Koo
 
Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014Gruter
 
[Gpg2권 구경원] 3.1 ai전략
[Gpg2권 구경원] 3.1 ai전략[Gpg2권 구경원] 3.1 ai전략
[Gpg2권 구경원] 3.1 ai전략KyeongWon Koo
 
[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기
[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기
[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기KyeongWon Koo
 
제5장 스태틱 메쉬
제5장 스태틱 메쉬제5장 스태틱 메쉬
제5장 스태틱 메쉬KyeongWon Koo
 
[Gpg2권]1.1 c++ 게임의 최적화
[Gpg2권]1.1 c++ 게임의 최적화[Gpg2권]1.1 c++ 게임의 최적화
[Gpg2권]1.1 c++ 게임의 최적화KyeongWon Koo
 
[페차쿠차] 3월 19일 아이디어에 미쳐보자!
[페차쿠차] 3월 19일 아이디어에 미쳐보자![페차쿠차] 3월 19일 아이디어에 미쳐보자!
[페차쿠차] 3월 19일 아이디어에 미쳐보자!KyeongWon Koo
 
선형연립방정식 가우스소거법
선형연립방정식 가우스소거법선형연립방정식 가우스소거법
선형연립방정식 가우스소거법KyeongWon Koo
 
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)Sang Don Kim
 
Svn에서 git으로 이주하기
Svn에서 git으로 이주하기Svn에서 git으로 이주하기
Svn에서 git으로 이주하기Seunghwa Song
 
[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조
[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조
[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조KyeongWon Koo
 
Python 내장 함수
Python 내장 함수Python 내장 함수
Python 내장 함수용 최
 
역동적인 애니메이션 Ik
역동적인 애니메이션 Ik역동적인 애니메이션 Ik
역동적인 애니메이션 IkKyeongWon Koo
 

Viewers also liked (20)

병렬 프로그래밍 패러다임
병렬 프로그래밍 패러다임병렬 프로그래밍 패러다임
병렬 프로그래밍 패러다임
 
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기
 
병렬 프로그래밍
병렬 프로그래밍병렬 프로그래밍
병렬 프로그래밍
 
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
박기헌 NDC12 초보 클라이언트 프로그래머의 병렬 프로그래밍 도전기
 
병렬프로그래밍과 Cuda
병렬프로그래밍과 Cuda병렬프로그래밍과 Cuda
병렬프로그래밍과 Cuda
 
빌드 속도를 올려보자
빌드 속도를 올려보자빌드 속도를 올려보자
빌드 속도를 올려보자
 
Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014
 
[Gpg2권 구경원] 3.1 ai전략
[Gpg2권 구경원] 3.1 ai전략[Gpg2권 구경원] 3.1 ai전략
[Gpg2권 구경원] 3.1 ai전략
 
[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기
[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기
[Gpg2권]4.7 인쇄해상도의 스크린샷 만들기
 
[데브루키] FOG
[데브루키] FOG[데브루키] FOG
[데브루키] FOG
 
제5장 스태틱 메쉬
제5장 스태틱 메쉬제5장 스태틱 메쉬
제5장 스태틱 메쉬
 
[Gpg2권]1.1 c++ 게임의 최적화
[Gpg2권]1.1 c++ 게임의 최적화[Gpg2권]1.1 c++ 게임의 최적화
[Gpg2권]1.1 c++ 게임의 최적화
 
[페차쿠차] 3월 19일 아이디어에 미쳐보자!
[페차쿠차] 3월 19일 아이디어에 미쳐보자![페차쿠차] 3월 19일 아이디어에 미쳐보자!
[페차쿠차] 3월 19일 아이디어에 미쳐보자!
 
선형연립방정식 가우스소거법
선형연립방정식 가우스소거법선형연립방정식 가우스소거법
선형연립방정식 가우스소거법
 
TBB 소개
TBB 소개TBB 소개
TBB 소개
 
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
 
Svn에서 git으로 이주하기
Svn에서 git으로 이주하기Svn에서 git으로 이주하기
Svn에서 git으로 이주하기
 
[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조
[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조
[Gpg2권 구경원] 3.4 rts 게임의 명령 큐잉을 위한 기반 구조
 
Python 내장 함수
Python 내장 함수Python 내장 함수
Python 내장 함수
 
역동적인 애니메이션 Ik
역동적인 애니메이션 Ik역동적인 애니메이션 Ik
역동적인 애니메이션 Ik
 

Similar to [0204 구경원] sse 병렬 프로그래밍

2강 텍스쳐 포맷과 기초 / 오타수정
2강 텍스쳐 포맷과 기초 / 오타수정2강 텍스쳐 포맷과 기초 / 오타수정
2강 텍스쳐 포맷과 기초 / 오타수정JP Jung
 
2강 텍스쳐 포맷과 기초
2강 텍스쳐 포맷과 기초2강 텍스쳐 포맷과 기초
2강 텍스쳐 포맷과 기초JP Jung
 
[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이
[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이
[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이GangSeok Lee
 
DevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptxDevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptxMUUMUMUMU
 
[조진현] [Kgc2011]direct x11 이야기
[조진현] [Kgc2011]direct x11 이야기[조진현] [Kgc2011]direct x11 이야기
[조진현] [Kgc2011]direct x11 이야기진현 조
 
[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유Hwan Min
 
Jnetpcap quickguide
Jnetpcap quickguideJnetpcap quickguide
Jnetpcap quickguideSukjin Yun
 
Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1YEONG-CHEON YOU
 
Comm manual kor(dasa sigma [rev.c])(2)
Comm manual kor(dasa sigma [rev.c])(2)Comm manual kor(dasa sigma [rev.c])(2)
Comm manual kor(dasa sigma [rev.c])(2)ganeshtajane
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9진현 조
 
2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)
2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)
2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)khuhacker
 
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)HYUNJEONG KIM
 
From Java code to Java heap_SYS4U I&C
From Java code to Java heap_SYS4U I&CFrom Java code to Java heap_SYS4U I&C
From Java code to Java heap_SYS4U I&Csys4u
 
Main Variable Program
Main Variable ProgramMain Variable Program
Main Variable Program경섭 심
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술henjeon
 

Similar to [0204 구경원] sse 병렬 프로그래밍 (20)

부팅
부팅부팅
부팅
 
2강 텍스쳐 포맷과 기초 / 오타수정
2강 텍스쳐 포맷과 기초 / 오타수정2강 텍스쳐 포맷과 기초 / 오타수정
2강 텍스쳐 포맷과 기초 / 오타수정
 
2강 텍스쳐 포맷과 기초
2강 텍스쳐 포맷과 기초2강 텍스쳐 포맷과 기초
2강 텍스쳐 포맷과 기초
 
[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이
[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이
[2010 CodeEngn Conference 04] hahah - Defcon 18 CTF 문제풀이
 
DevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptxDevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptx
 
[조진현] [Kgc2011]direct x11 이야기
[조진현] [Kgc2011]direct x11 이야기[조진현] [Kgc2011]direct x11 이야기
[조진현] [Kgc2011]direct x11 이야기
 
Sha1
Sha1Sha1
Sha1
 
[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유
 
Jnetpcap quickguide
Jnetpcap quickguideJnetpcap quickguide
Jnetpcap quickguide
 
Redis
RedisRedis
Redis
 
Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1
 
Comm manual kor(dasa sigma [rev.c])(2)
Comm manual kor(dasa sigma [rev.c])(2)Comm manual kor(dasa sigma [rev.c])(2)
Comm manual kor(dasa sigma [rev.c])(2)
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
 
2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)
2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)
2015 제2회 동아리 해커 세미나 - 병렬컴퓨팅 소개 (16기 김정현)
 
System+os study 2
System+os study 2System+os study 2
System+os study 2
 
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
 
From Java code to Java heap_SYS4U I&C
From Java code to Java heap_SYS4U I&CFrom Java code to Java heap_SYS4U I&C
From Java code to Java heap_SYS4U I&C
 
Main Variable Program
Main Variable ProgramMain Variable Program
Main Variable Program
 
[IBM 서버] POWER9
[IBM 서버] POWER9[IBM 서버] POWER9
[IBM 서버] POWER9
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
 

[0204 구경원] sse 병렬 프로그래밍

  • 1. SSE 병렬 프로그래밍 데브루키 돼지고기(구경원)
  • 2. SIMD. • Single Instruction Multiple Data • CPU에서 지원하는 일종의 명령어 셋. • 한번의 연산으로 다수의 데이터를 처리할 수 있다. • SISD - Single Instruction Single Data • SIMD - Single Instruction Multiple Data • MISD - Multiple Instruction Single Data • MIMD - Multiple Instruction Multiple Data
  • 3. SIMD. Input Data Output Data SISD 명령어 Input Data Output Data SIM D 명령어
  • 4. SIMD. • SISD … … 11 10 v 8 7 6 5 4 3 2 1 • SIMD 연산의 방향 32 bit 32 bit 32 bit 32 bit 4 3 2 1 4 3 2 1 + + + + 8 7 6 5 8 7 6 5 + + + + 12 11 10 9 + + + + 16 15 14 13 = = = = 40 36 32 28 4값의 합 = 136
  • 5. SIMD 구현 방법. • 어셈블리 SIMD 명령어 • Intrinsic 함수 • Vector Class SIMD 명령어 Intrinsic 함수 Vector Class xmm0 __m128i Is16vec8 xmm1 __m128 Is32vec4 ~ ~ __m128d F32vec4 xmm7 F64vec2
  • 7. SIMD 구현 조건. • 프로젝트의 중요 부분 또는 병목 지점인가. • SIMD 구조에 적합한가. • 성능향상에 도움이 되어지는가. • 정수형, 실수형 인지 파악. • 128bit에 담을 수 있는 데이터 개수 고려. • 제작기간, 디버깅 테스트 기간 고려. • 구현 도구 결정. • SISD와 SIMD 성능 비교 테스트.
  • 8. SSE. • Streaming SIMD Extensions • XMM 128비트 레지스터 8개가 존재. • 인텔이 1999년 펜티엄3 프로세서에 도입. • FLOAT, POINT. 비교로직 등 다양한 연산 가능. Packing 사이즈 byte short integer 병렬 연산 개수 16 8 4 C 코드와 성능 차이 4~6배 2배 10~30%
  • 10. IA-32 / 64 레지스터
  • 11. SIMD 연산 타입 32 bit A3 32 bit A2 32 bit A1 32 bit A0 Scalar 덧셈 계산 + 32 bit B3 32 bit B2 32 bit B1 32 bit B0 = 32 bit A3 32 bit A2 32 bit A1 32 bit A0+ B0 32 bit A3 32 bit A2 32 bit A1 32 bit A0 Packed 덧셈 계산 + + + + 32 bit B3 32 bit B2 32 bit B1 32 bit B0 = = = = 32 bit A3+ B3 32 bit A2+ B2 32 bit A1+ B1 32 bit A0+ B0
  • 12. 중요 어셈블리 • mov • add / sub • mul / div • inc / dec • shl / shr • cmp / jp
  • 13. 어셈블리 예제. __asm { pushad mov eax, A mov ebx, B add eax, ebx mov C, eax popad }
  • 14. 어셈블리 예제. __asm { pushad mov ebx, 15 mov eax, A mul ebx mov C, eax popad }
  • 15. 어셈블리 예제. __asm { pushad mov eax, 17 cdq //32 bit를 64 bit로 확장 //convert double word to quad word mov ebx, A div ebx mov B, eax mov C, edx popad }
  • 16. 어셈블리 예제. __asm { pushad mov eax, 0 LOOP: //필요한 연산 inc eax cmp eax, 1000 jne LOOP mov nValue, eax popad }
  • 17. SIMD 명령어 • 정수형과 실수형 두 가지 병렬 연산 방식이 있다. • Pack 형식에 따라 연산 방식이 달라짂다. • MMX 에서는 64bit 병렬 연산만 가능했지만 SSE 로 넘어오면서 128bit 병렬 연산이 가능해졌다. • 구현코드가 CPU에서 똑같이 동작한다. • 디버깅이 어렵고, 가독성이 앆좋다.
  • 18. 명명법 P <SIMD_op> <suffix> 접미사 원어 사이즈 의 미 S signed - 양수값을 의미하는 접미사로 사이즈를 의미하는 단어 앞에 오게 된다. U unsigned - +- 부호를 갖는 데이터형임을 의미한다. B Byte 8 bit 해당 데이터는 8 bit 정수 형 16개를 연산할 수 있다. W Word 16 bit 해당 데이터는 16 bit 정수 형 8개를 연산할 수 있다. D DoubleWord 32 bit 해당 데이터는 32 bit 정수 형 4개를 연산할 수 있다. Q QuadWord 64 bit 해당 데이터는 64 bit 정수 형 2개를 연산할 수 있다.
  • 19. 메모리 align, unalign • 정렬된 메모리를 사용하는 것이 빠르다. • 정렬된 메모리 • __declspec( align(16) ) int array[100]; • 정렬되지 않은 메모리 • Int array[100]
  • 20. MOVDQU Move Unaligned Double Quad word • 128bit 레지스트 또는 128bit 메모리에 정 렬되지 않은 값을 읽어올 때 사용한다 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 Byte Unaligned Memory 8 7 6 5 4 3 2 1 M OVDQU 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit xmm0 레지스터 8 7 6 5 4 3 2 1
  • 21. MOVDQA Move aligned Double Quad word • 128bit 레지스터 또는 128bit 메모리에 정렬되어 있는 값을 읽어올 때 사용 한다. • 메모리가 정렬되어 있기 때문에 읽어오는 속도 가 빠르다. 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 Byte Aligned Memory 8 7 6 5 4 3 2 1 M OVDQA 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit xmm0 레지스터 8 7 6 5 4 3 2 1
  • 22. 논리연산 32 bit 32 bit 32 bit 32 bit SourceA 1 1 0 0 SourceB 1 0 1 0 PAND 1 0 0 0 POR 1 1 1 0 PXOR 0 1 1 0 PANDN 0 0 1 0
  • 23. PADDD (Packed Add) • 더하기 연산을 한다 32 bit 32 bit 32 bit 32 bit xmm0 4 3 2 1 paddd + + + + xmm1 8 7 6 5 = = = = xmm0 12 10 8 6
  • 24. PADDD (Packed Add) int IntArrayA[4] = { 1,2,3,4 }; int IntArrayB[4] = { 5,6,7,8 }; int IntResult[4] = {0}; __asm { pushad movdqu xmm0, IntArrayA movdqu xmm1, IntArrayB paddd xmm0, xmm1 movdqu IntResult, xmm0 popad emms }
  • 25. PADDD (Packed Add) • SISD … … 11 10 v 8 7 6 5 4 3 2 1 • SIMD 연산의 방향 32 bit 32 bit 32 bit 32 bit 4 3 2 1 4 3 2 1 + + + + 8 7 6 5 8 7 6 5 + + + + 12 11 10 9 + + + + 16 15 14 13 = = = = 40 36 32 28 4값의 합 = 136
  • 26. 최대값 구하기 short GetMaxValueC(const short *pShortArray,const int nSize) { short MaxValue = 0; for(int i = 0; i< nSize ; i++) { if(pShortArray[i] > MaxValue ) MaxValue = pShortArray[i]; } return MaxValue; }
  • 27. 최대값 구하기 const short* pShort = pShortArray; //스택포인터변수로받아온다. int nLoopCount = (nSize / 8)*16; //8배수개수를한번에계산 int nRemain = nSize % 8; //8배수나머지영역은C로구현 short nMaxValue = 0; //결과값을가지고있을메모리변수
  • 28. 최대값 구하기 • __asm • { • pushad • mov eax, pShort • mov esi, 0 • • mov ecx, nLoopCount • pxor xmm1, xmm1 • FINDLP: • movdqu xmm0, [eax+esi] . • pmaxsw xmm1, xmm0 • • add esi, 16 . • cmp esi, ecx • jne FINDLP • movdqu MaxValueArray, xmm1 • popad • emms • }
  • 29. 최대값 구하기 • for( unsigned char Count = 0; Count < 8 ; Count++) • { • if( MaxValueArray[Count] > nMaxValue ) • nMaxValue = MaxValueArray[Count]; • } • • if( nRemain != 0) • { • for( int i = nSize-nRemain; i< nSize; i++) • { • if(pShortArray[i] > nMaxValue ) • nMaxValue = pShortArray[i]; • } • }
  • 30. GetLength() f = sqrtf(x_ * x_ + y_ * y_ + z_ * z_); • FLOAT* p = &f; w_ = 0.0f; • __asm { – mov ecx, p – mov esi, this – movups xmm0, [esi] – mulps xmm0, xmm0 – movaps xmm1, xmm0 – shufps xmm1, xmm1, 01001110b – addps xmm0, xmm1 – movaps xmm1, xmm0 – shufps xmm1, xmm1, 00010001b – addps xmm0, xmm1 – sqrtss xmm0, xmm0 – movss [ecx], xmm0 • }
  • 32. Intrinsic 함수 • 코드의 분석이 쉽다. • SIMD 명령어를 inline 함수로 구현하여, 함수의 성능은 SIMD 명령어 셋과 차이가 별로 없다. • Scalar 형 intrinsic 함수는 어셈블리 SIMD 명령 어 보다 약간의 성능저하가 있을 수 있다. • SIMD 명령어 보다 코드 작성에 편리하다.
  • 33. 명명법 _mm_<intrin_op>_<suffix> 문자 데이터 타입 s 32bit 실수형 (single-precision floating point) d 64bit 실수형 (double-precision floating point) i128 128bit signed 정수 (signed 128-bit integer) i64 64bit signed 정수 (signed 64-bit integer) u64 64bit unsigned 정수 (unsigned 64-bit integer) i32 32bit signed 정수 (signed 32-bit integer) u32 32bit unsigned 정수 (unsigned 32-bit integer) i16 16bit signed 정수 (signed 16-bit integer) u16 16bit unsigned 정수 (unsigned 16-bit integer) i8 8bit signed 정수 (signed 8-bit integer) u8 8bit unsigned 정수 (unsigned 8-bit integer)
  • 34. Intrinsic 함수 • 헤더 파일 include • - #include <xmmintrin.h> SSE - #include <emmintrin.h> SSE2 - #include <pmmintrin.h> SSE3 - #include <smmintrin.h> <nmmintrin.h> SSE4
  • 35. __m128 자료형 • SIMD 연산을 위한 자료형으로 XMM 레지스트와 1대 1 대응되는 구조체이다. ___m128i 32 bit integer 32 bit integer 32 bit integer 32 bit integer
  • 36. Intrinsic LOAD. STORE __m128i r = _mm_load_si128(__m128i const *p) 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16Byte Align Memory p p[7] p[6] p[5] p[4] p[3] p[2] p[1] p[0] __m128i r r[7] r[6] r[5] r[4] r[3] r[2] r[1] r[0] void _mm_st ore_si128(__m128i *p, __m128i b) 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit 16 bit __m128i b b[7] b[6] b[5] b[4] b[3] b[2] b[1] b[0] 16Byte Align Memory p p[7] p[6] p[5] p[4] p[3] p[2] p[1] p[0]
  • 37. Intrinsic 함수 short Source[8] = {1,2,3,4,5,6,7,8}; short Dest[8] = {0}; __m128i xmm0 = _mm_loadu_si128((__m128i*)Source); __m128i xmm1 = xmm0; _mm_storeu_si128((__m128i*)Dest, xmm1);
  • 38. Intrinsic ADD. SUB __m128i R = _mm_add_epi16(__m128i a, __m128i b) __m128i a a7 a6 a5 a4 a3 a2 a1 a0 + + + + + + + + __m128i b b7 b6 b5 b4 b3 b2 b1 b0 = = = = = = = = __m128i r a7+b7 a6+b6 a5+b5 a4+b4 a3+b3 a2+b2 a1+b1 a0+b0 __m128i R = _mm_sub_epi16(__m128i a, __m128i b) __m128i a a7 a6 a5 a4 a3 a2 a1 a0 - - - - - - - - __m128i b b7 b6 b5 b4 b3 b2 b1 b0 = = = = = = = = __m128i r a7-b7 a6-b6 a5-b5 a4-b4 a3-b3 a2-b2 a1-b1 a0-b0
  • 39. Intrinsic MUL __m128i R = _mm_mullo_epi16(__m128i a, __m128i b) __m128i a a7 a6 a5 a4 a3 a2 a1 a0 * * * * * * * * __m128i b b7 b6 b5 b4 b3 b2 b1 b0 = = = = = = = = __m128i r a7*b7 a6*b6 a5*b5 a4*b4 a3*b3 a2*b2 a1*b1 a0*b0
  • 40. Intrinsic MAX. MIN __m128i R = _mm_max_epi16(__m128i a, __m128i b) __m128i a a7 a6 a5 a4 a3 a2 a1 a0 max max max max max max max max __m128i b b7 b6 b5 b4 b3 b2 b1 b0 = = = = = = = = __m128i r max(a7,b7) max(a6,b6) max(a5,b5) max(a4,b4) max(a3,b3) max(a2,b2) max(a1,b1) max(a0,b0) __m128i R = _mm_min_epi16(__m128i a, __m128i b) __m128i a a7 a6 a5 a4 a3 a2 a1 a0 min min min min min min min min __m128i b b7 b6 b5 b4 b3 b2 b1 b0 = = = = = = = = __m128i r min(a7,b7) min(a6,b6) min(a5,b5) min(a4,b4) min(a3,b3) min(a2,b2) min(a1,b1) min(a0,b0)
  • 41. 최대값 구하기 const short* pShort = pShortArray; int nRemain = nSize % 8; short nMaxValue = 0; short MaxValueArray[8] ={0}; __m128i XMMCurrentValue; __m128i XMMMaxValue; for(unsigned int Index =0 ; Index < nSize; Index+=8) { XMMCurrentValue = _mm_loadu_si128((__m128i*)(pShortArray+Index)); //16byte 씩읽어온다. XMMMaxValue = _mm_max_epi16(XMMMaxValue, XMMCurrentValue); //16byte 씩더한다. }
  • 43. Vector 클래스 • Intrinsic 데이터형 또는 함수를 클래스화시 킨 라이브러리. • Intrinsic 를 이용할 때 보다 직관적이고 사 용이 편리하다. • 연산자 오버로딩으로 만들어져 있다.
  • 44. Vector 클래스 • 명명법 – <type><signedness><bits>vec<elements> Iu32vec4 32bit unsigned int 형 정수를 4개 담고 있는 vector 클래스. Fs16vec8 8bit signed short 형 실수를 8개 담고 있는 vector 클래스.
  • 45. Vector 클래스 class 부호 pack 데이터 타입 pack 사이즈 pack 개수 해더 파일 I128vec1 unspecified __m128i 128 1 dvec.h I64vec2 unspecified __int64 64 2 dvec.h Is64vec2 signed __int64 64 2 dvec.h Iu64vec2 unsigned __int64 64 2 dvec.h I32vec4 unspecified int 32 4 dvec.h Is32vec4 signed int 32 4 dvec.h Iu32vec4 unsigned int 32 4 dvec.h I16vec8 unspecified short 16 8 dvec.h Is16vec8 signed short 16 8 dvec.h Iu16vec8 unsigned short 16 8 dvec.h I8vec16 unspecified char 8 16 dvec.h Is8vec16 signed char 8 16 dvec.h Iu8vec16 unsigned char 8 16 dvec.h
  • 46. Vector 클래스 __asm{ movaps xmm0, a movaps xmm1, b addps xmm0, xmm1 movaps c, xmm0 } #include < xmmintrin.h > __m128 a, b, c; c = _mm_add_ps( a, b); #include <fvec.h> F32vec4 A, B, C C = A + B;
  • 47. Vector 클래스 읽고. 쓰기 __declspec(align(16)) short A[8] = {1,2,3,4,5,6,7,8}; __declspec(align(16)) short R[8] = {0}; Is16vec8 Vector(1,2,3,4,5,6,7,8); //역순으로 8부터 입력 _mm_store_si128((__m128i *)R, Vector); //intrinsic 함수로 쓰기 printf("Store : %d, %d, %d, %d, %d, %d, %d, %dn" ,R[0],R[1],R[2],R[3],R[4],R[5],R[6],R[7]); Is16vec8 *a = (Is16vec8 *)A; //포인터 캐스팅으로 바로 읽 기 Is16vec8 *r = (Is16vec8 *)R; *r = *a; //대입 연산 printf("Store : %d, %d, %d, %d, %d, %d, %d, %dn" ,R[0],R[1],R[2],R[3],R[4],R[5],R[6],R[7]); return 0;
  • 48. Vector 클래스 사칙연산 Is16vec8 A; Is16vec8 B; Is16vec8 R; R = A + B; //덧셈 연산 R += A; R = A - B; //뺄셈 연산 R -= A; R = A * B; //곱셈 연산 R *= A; R = mul_high( A, B ); //곱셈 상위 bit R = mul_add( A, B); //곱 합 연산
  • 49. 최대값 구하기 const short* pShort = pShortArray; int nRemain = nSize % 8; short nMaxValue = 0; short MaxValueArray[8] ={0}; Is16vec8* XMMCurrentValue; Is16vec8 XMMMaxValue; for(unsigned int Index =0 ; Index < nSize; Index+=8) { XMMCurrentValue = (Is16vec8*)(pShortArray+Index); XMMMaxValue = simd_max(XMMMaxValue,* XMMCurrentValue); }
  • 51. 마무리 - SSE를 사용하면 C/C++ 보다 빠른 성능 향상을 볼 수 있 다. - 멀티코어 시대에 SSE의 사용은 미래를 대비하는 일이다. - 아직까지 가독성의 문제가 남아있다. - 반복되는 계산량이 많은 부분에서 많은 이득을 볼 수 있다. - 캐쉬라인 정렬이 되어있어야 효율적이다.
  • 52. Q&A
  • 53. END