SlideShare ist ein Scribd-Unternehmen logo
1 von 45
Downloaden Sie, um offline zu lesen
LLVMで遊ぶ	
  
整数圧縮とか、x86向け自動ベクトル化とか	
                            2013/3/30	
  
             maropu@x86/64最適化勉強会5	
  	
  




                                            1
clang	
       LLVMで遊ぶ	
  
整数圧縮とか、x86向け自動ベクトル化とか	
                            2013/3/30	
  
             maropu@x86/64最適化勉強会5	
  	
  




                                            2
本日の概要	
•  なんでお前clang(LLVM)の話してんの?	
  
  –  RDBMS関連の話題で最近良く扱われるため勉強中	
  
  –  今書いている整数圧縮のコードをより高速化したい	
  

•  整数圧縮ライブラリ:	
  vpacker	
  
  –  hCps://github.com/maropu/vpacker	
  


•  clangのx86向け自動ベクトル化	
  
  –  SIMDを使用した命令列への自動変換	
  




                                            3
LLVMとの出会い・・・	




                 4
DB業界におけるLLVMの利活用	
•  SQLによる関係代数の処理をLLVM-­‐JITで改善	
  
  –  既存DBのSQL処理系*1は冗長的で非効率	
  
                              *1SQLコンパイラとSQL実行エンジンのこと




             Thomas Neumann, Efficiently Compiling Efficient Query Plans for
                                       Modern Hardware, Proc. of VLDB’11
                                                                               5
DB業界におけるLLVMの利活用	
•  Cloudera	
  ImpalaにおけるLLVMの利用	
  
  •  SQL対応の分散クエリエンジン	
  
  •  aggregaQon/join/scanの一部をJITで効率化	
  
  •  hCps://github.com/cloudera/impala	
  




  引用: http://www.theregister.co.uk/2012/10/24/cloudera_hadoop_impala_real_time_query/	
                                                                                6
整数圧縮ライブラリ: vpacker	



                       7
vpacker	
•  32/64-­‐bit整数列を圧縮するライブラリ(C/C++/Java)	
  
  –  hCps://github.com/maropu/vpacker	
  
  	
  
•  前提条件:	
  正の歪度をもつ整数列を効率的に圧縮	
  
  –  大半が小さい値で、稀に大きな値が発生	
  


•  ライブラリの特徴	
  
  –  少ないメモリ量で圧縮&展開	
  
  –  ILPを考慮した展開処理	
  -­‐	
  γ/δ符号と比べて速い	
  
  –  動的計画法による圧縮率の最適化	
  
  –  ヘッダファイルの読み込みのみで使用可能	
  

                                              8
vpacker	
  –	
  使い方 	




                         9
近年の整数圧縮手法	
     ~1990’s	
     ~2000’s	
                                 ~2013	


                                                   BP/SIMD-BP(2012)	


γ/δ/Variable-Byte符号	
                            Varint-G8IU(2011)	
                               Simple9(2005)	
                                          Simple16(2009)	


                                            Simple8b(2010)	


                                                   VSEncoding(2010)	
                               PForDelta(2006)	
                                      OPTPForDelta(2009)	
                                      SIMD-FastPFor/SimplePFor(2012)	
                                                                        10
近年の整数圧縮手法	
     ~1990’s	
     ~2000’s	
                                 ~2013	


                                                   BP/SIMD-BP(2012)	


γ/δ/Variable-Byte符号	
                            Varint-G8IU(2011)	
                               Simple9(2005)	
                                          Simple16(2009)	


                                        Simple8b(2010)	
     -  現在、最速の手法で秒間2000M個整数を展開
     -  vpackerは20130330現在の実装で秒間600〜700M程度	
                                              VSEncoding(2010)	
                            PForDelta(2006)	
                                      OPTPForDelta(2009)	
                                      SIMD-FastPFor/SimplePFor(2012)	
                                                                        11
vpacker	
  –	
  内部構造	
  
•  圧縮データのバイナリフォーマット	
  
   –  前半のディスクリプタ部と圧縮したデータ部で構成	
  

       ディスクリプタ部(desc)	
     圧縮データ部(in)	



      1-byteのディスクリプタの列     圧縮された整数データ	
       後半の圧縮したデータが
    どのように格納されているかを記録	




                                           12
vpacker	
  –	
  内部構造	
  
•  圧縮データのバイナリフォーマット	
  


       ディスクリプタ部(desc)	
                    圧縮データ部(in)	

      1-byteのデータに固定長1-bitで8個の整数が格納	

   void unpack1_8(const char *in, uint32_t *out) {
        *out++ = in[0] & 0x01;
        *out++ = (in[0] >> 1) & 0x01;
        *out++ = (in[0] >> 2) & 0x01;
          ...
        *out++ = (in[0] >> 7) & 0x01;
    }	


                                                          13
vpacker	
  –	
  内部構造	
•  圧縮データのバイナリフォーマット	
  
        2-byteのデータに固定長2-bitで8個の整数が格納	


       ディスクリプタ部(desc)	
                    圧縮データ部(in)	

      1-byteのデータに固定長1-bitで8個の整数が格納	

   void unpack2_8(const char *in, uint32_t *out) {
        *out++ = in[0] & 0x03;
        *out++ = (in[0] >> 2) & 0x03;
        *out++ = (in[0] >> 4) & 0x03;
          ...
        *out++ = (in[1] >> 6) & 0x03;
    }	


                                                          14
vpacker	
  –	
  内部構造	
•  復元処理の動作概要	
  
       2-byteのデータに固定長2-bitで8個の整数が格納	


      ディスクリプタ部(desc)	
            圧縮データ部(in)	

     1-byteのデータに固定長1-bitで8個の整数が格納	

   while (1) {
     switch (*desc++) {
       case 1-bitで8個の整数を展開: unpack1_8(in, out); break;
       case 2-bitで8個の整数を展開: unpack2_8(in, out); break;
        ...
     }
                  -  VMのインタプリタ的な処理の流れ
   }	
            -  descは1-byteのため最大256分岐(分岐数は設計による)	

                                                          15
vpacker	
  –	
  内部構造	
•  LLVM-­‐JITを用いてwhile-­‐switchを軽量化	
  
  –  共通する復元処理をまとめることでjmp命令を除去	
  

      ディスクリプタ部(desc)	
               圧縮データ部(in)	


                              「前提条件」より大半の復元処理は
                                  一部の関数に集中	
   while (1) {
     switch (*desc++) {
       case 1-bitで8個の整数を展開: unpack1_8(in, out); break;
       case 2-bitで8個の整数を展開: unpack2_8(in, out); break;
        ...
     }
   }	


                                                         16
vpacker	
  –	
  内部構造	
•  呼び出しが集中している関数を高速化	
  
  –  基本はSIMDを利用したデータ並列性の向上	
  

      ディスクリプタ部(desc)	
               圧縮データ部(in)	


                             呼び出しが集中している関数を高速化	
   while (1) {
     switch (*desc++) {
       case 1-bitで8個の整数を展開: unpack1_8(in, out); break;
       case 2-bitで8個の整数を展開: unpack2_8(in, out); break;
        ...
     }
   }	


                                                         17
gcc(v4.8)の自動ベクトル化	
•  この関数*1ってどんな機械語に変換されるの?	
  
   –  処理に依存関係が無く,ベクトル化しやすそうな印象	
  

   void unpack1(const char *in, uint32_t *out, int n) {
        for (int i = 0; i < n; i++) {
              *out++ = in[0] & 0x01;
              *out++ = (in[0] >> 1) & 0x01;
              *out++ = (in[0] >> 2) & 0x01;
                ...
              *out++ = (in[0] >> 7) & 0x01;
        }
   }	


*1 現実に即して,ループ回数(n)を指定できるように変更しました	
                                                          18
gcc(v4.8)の自動ベクトル化	
•  この関数ってどんな機械語に変換されるの?	
  
 –  処理に依存関係が無く,ベクトル化しやすそうな印象	
  

  void unpack1(const char *in, uint32_t *out, int n) {
       for (int i = 0; i < n; i++) {
             *out++ = in[0] & 0x01;
             *out++ = (in[0] >> 1) & 0x01;
             *out++ = (in[0] >> 2) & 0x01;
               ...
             *out++ = (in[0] >> 7) & 0x01;
       }
  }	
         重要) コンパイルする前に自動ベクトル化されやすいように前処理	


                                                         19
gcc(v4.8)の自動ベクトル化	
•  この関数ってどんな機械語に変換されるの?	
  
 –  処理に依存関係が無く,ベクトル化しやすそうな印象	
  

  void unpack1(const char *in, uint32_t *out, int n) {
       for (int i = 0; i < n; i++) {
             for (int j = 0; j < 8; j++)
                    *out++ = (*in >> j) & 0x01;
             in++;
       }
  }	
        gccの場合、SLP(Superword-Level Parallelism)による最適化より
              Loop Vectorizerに任せたほうが良いらしいです	




                                                          20
gcc(v4.8)の自動ベクトル化	
•  この関数ってどんな機械語に変換されるの?	
  
 –  処理に依存関係が無く,ベクトル化しやすそうな印象	
  

  void unpack1(const char * __restrict__ in,
                  uint32_t * __restrict__ out, int n) {
       for (int i = 0; i < n; i++) {
             for (int j = 0; j < 8; j++)
                    *out++ = (*in >> j) & 0x01;
             in++;
       }
  }	
          __restrict__を付与してin/outを呼び出し側で16Bにアライメント	




                                                          21
gcc(v4.8)の自動ベクトル化	
      •  一部だけ抜粋	
  &	
  並び替え(’gcc	
  -­‐O3’)	
  
      movdqu      (%r9), %xmm1   // in - %xmm1

         pxor        %xmm2, %xmm2
         pcmpgtb     %xmm1, %xmm2
         movdqa      %xmm1, %xmm3
         punpckhbw   %xmm2, %xmm1
      punpcklbw   %xmm2, %xmm3

      pxor      %xmm2, %xmm2
   movdqa    %xmm3, %xmm4
      pcmpgtw   %xmm3, %xmm2
      punpcklwd %xmm2, %xmm4

         movdqa      %xmm4, %xmm5
         pand        %xmm0, %xmm5   // %xmm1=[0x01, 0x01, 0x01, 0x01]
         ....	

                                                                        22
gcc(v4.8)の自動ベクトル化	
      •  一部だけ抜粋	
  	
  並び替え(’gcc	
  -­‐O3’)	
  
      movdqu      (%r9), %xmm1   // in - %xmm1

         pxor        %xmm2, %xmm2
         pcmpgtb     %xmm1, %xmm2
         movdqa      %xmm1, %xmm3
         punpckhbw   %xmm2, %xmm1
      punpcklbw   %xmm2, %xmm3 バイトからワードに符号拡張	

      pxor      %xmm2, %xmm2
   movdqa    %xmm3, %xmm4
      pcmpgtw   %xmm3, %xmm2
      punpcklwd %xmm2, %xmm4 ワードからダブルワードに符号拡張	

         movdqa      %xmm4, %xmm5
         pand        %xmm0, %xmm5   // %xmm1=[0x01, 0x01, 0x01, 0x01]
         ....	
                  0x01でマスクして展開処理完了	
                                                                        23
gcc(v4.8)の自動ベクトル化	
      •  一部だけ抜粋	
  	
  並び替え(’gcc	
  -­‐O3’)	
  
      movdqu      (%r9), %xmm1    // in - %xmm1

         pxor        %xmm2, %xmm2
         pcmpgtb     %xmm1, %xmm2
         movdqa      %xmm1, %xmm3
         punpckhbw   %xmm2, %xmm1
      punpcklbw   %xmm2, %xmm3 バイトからワードに符号拡張	

      pxor      %xmm2, %xmm2
   movdqa    %xmm3, %xmm4
      pcmpgtw   %xmm3, %xmm2
      punpcklwd %xmm2, %xmm4 ワードからダブルワードに符号拡張	
                ‘n  15’で分岐させてLoopを全てinline化するアグレッシブな最適化
         movdqa       %xmm4, %xmm5
                →’n = 15’はベクトル化されていないパスに分岐	
         pand         %xmm0, %xmm5 // %xmm1=[0x01, 0x01, 0x01, 0x01]
         ....	
                    0x01でマスクして展開処理完了	
                                                                       24
clangのx86向け自動ベクトル化	
  



                         25
clangと自動ベクトル化	
•  LLVM上に実装されたC/C++用フロントエンド	
  
    –  hCp://clang.llvm.org/index.html	
  
•  Auto-­‐VectorizaQon	
  in	
  LLVM	
  
    –  hCp://llvm.org/docs/Vectorizers.html	
  
•  Linpackを用いた性能評価	
  
    –  with	
  loop	
  vectorizaQon	
  at	
  -­‐O3	
  running	
  on	
  a	
  Sandybridge	
  




                                                            自動ベクトル化の有無で
                                                             性能差が3倍程度!	


                                                                                              26
clangにおける2種類のVectorizer	
•  Basic-­‐Block(BB)	
  Vectorizer	
  –	
  SLP	
  in	
  gcc	
  	
  
     –  v3.1で”	
  -­‐mllvm	
  –vectorize”として導入	
  
     –  最適化の対象が「Basic	
  Block」	
  
     –  歴史的に実装されたのはコチラが先	
  


•  Loop	
  Vectorizer	
  
     –  v3.2でようやく”	
  -­‐mllvm	
  –vectorize-­‐loops”として導入	
  
     –  「Unroll+BB	
  Vectorizer」にLoop間依存解析を加えたもの	
  
     –  自動ベクトル化の制約(v3.2のReleaseNotesより)	
  
          •  Loop枚のカウントは”1”のみ	
  
          •  InducQon変数は一番内側のLoopのみ使用可能	
  


                                                                      27
clangの自動ベクトル化パラメータ	
•  clang-­‐v3.2を利用(2013/3/30現在最新)	
  
    –  デフォルトで自動ベクトル化は全てOFF	
  
    –  v3.3からLoop	
  Vectorizerはデフォルトに	
  
    	
  
•  -­‐mllvm	
  –vectorize,	
  -­‐mllvm	
  –vectorize-­‐loops	
  
    –  -­‐O2/-­‐O3との併用が必要	
  
    –  -­‐Osはコード増加が発生しない場合に適用	
  
•  -­‐mllvm	
  –bb-­‐vectorize-­‐aligned-­‐only	
  
    –  アラインされたstore/loadのみを最適化に使用	
  
•  -­‐mllvm	
  –force-­‐vector-­‐width=X	
  
    –  最適化で使用するベクトル要素数をXで指定	
  

                                                                   28
その他の補助パラメータ	
•  -­‐mllvm	
  –unroll-­‐allow-­‐parQal	
  
       –  Loop内の部分的なUnrollを可能に	
  
•  -­‐mllvm	
  –unroll-­‐runQme	
  
       –  実行時にLoopを数えてUnroll可能に	
  
•  -­‐funsafe-­‐math-­‐opQmizaQons,	
  -­‐ffast-­‐math	
  
       –  浮動小数点演算にIEEE/ISO仕様外の最適化を適用	
  


•  他の関連するパラメータは以下の資料が詳しい	
  
       –  Auto-­‐vectorizaQon	
  with	
  LLVM	
  
       –  hCp://llvm.org/devmtg/2012-­‐04-­‐12/Slides/Hal_Finkel.pdf	
  
	
  
                                                                       29
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.1#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
  
                 void test1(float * __restrict__ a,
                                float * __restrict__ b, int n) {
                         for (int i = 0; i  n; i++)
                               a[i] += b[i];
                    }	




                                                                   30
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.1#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
                                      %rdiと%rsiは16Bに揃えてあるのに
                .LBB0_2:                 なぜかmovapsに変換されない?	
                    movups 16(%rdi,%rax,4), %xmm1
                    movups 16(%rsi,%rax,4), %xmm0
                    addps %xmm1, %xmm0
                    movups (%rdi,%rax,4), %xmm1
                    movups (%rsi,%rax,4), %xmm2
                    movups %xmm0, 16(%rdi,%rax,4)
                    addps %xmm1, %xmm2
                    movups %xmm2, (%rdi,%rax,4)
                    addq $8, %rax
                    cmpq %rax, %rcx
                    jne .LBB0_2	
                                  31
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.2#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
  
                 void test2(float * __restrict__ a,
                                float * __restrict__ b, int n) {
                         for (int i = 0; i  n; i += 2)
                               a[i] += b[i];
                    }	




                                                                   32
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.2#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
  
                .LBB0_2:
                    movss (%rsi,%rax,4), %xmm0
                    addss (%rdi,%rax,4), %xmm0
                    movss %xmm0, (%rdi,%rax,4)
                    addq $2, %rax
                    cmpl %edx, %eax
                    jl   .LBB0_2	




                                                                   33
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.3#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
  
                 void test3(float * __restrict__ a,
                                float * __restrict__ b, int n) {
                         for (int i = 0; i  n; i += 1) {
                               for (int j = 0; j  SIZE; j++)
                                      a[i * SIZE + j] += b[i * SIZE + j];
                         }
                    }	




                                                                            34
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.3#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
                   .LBB1_22: # = The Inner Loop
                         movups (%rbx), %xmm2
                         movups 16(%rbx), %xmm1
                         movups (%rax), %xmm0
                         movups 16(%rax), %xmm3
                         addps %xmm2, %xmm0
                         addps %xmm1, %xmm3
                         movups %xmm3, 16(%rbx)
                         movups %xmm0, (%rbx)
                         addq $32, %rbx
                         addq $32, %rax
                         addq $-8, %rdi
                         jne .LBB1_22	
                                                                   35
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.4#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
  
                 float test4(float * __restrict__ a, int n) {
                          float S = 0.0;
                          for (int i = 0; i  n; i += 1)
                                S += a[i];
                          return S;
                    }	




                                                                   36
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.4#	
  
       –  clang	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize-­‐loops	
  
	
  
                 .LBB0_1:
                        addss (%rdi), %xmm0
                        addq $4, %rdi
                        decl %esi
                        jne .LBB0_1	

                 浮動小数点演算は結合則が成り立たないため、こういう命令列に
                 →clangにも’-ffast-math’があるが、出力する命令は同じだった	




                                                                   37
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.4#	
  
       –  gcc	
  -­‐O3	
  -­‐ffast-­‐math	
  
	
                  .L33:
                            addps (%rax), %xmm0
                            addq $16, %rax
                            cmpq %rdx, %rax
                            jne .L33
                            movaps %xmm0, %xmm1
                            movhlps %xmm0, %xmm1
                            addps %xmm0, %xmm1
                            movaps %xmm1, %xmm0
                            shufps $85, %xmm1, %xmm0
                            addps %xmm1, %xmm0
                            unpcklps    %xmm0, %xmm0	
                                                                 38
WriQng	
  Vectorizer-­‐Friendly	
  Code	
  in	
  clang	
  	
  
•  example.4#	
  
       –  gcc	
  -­‐O3	
  -­‐ffast-­‐math	
     ベクトル加算して	
	
                  .L33:
                            addps (%rax), %xmm0
                            addq $16, %rax
                            cmpq %rdx, %rax
                            jne .L33              水平加算	
                            movaps %xmm0, %xmm1
                            movhlps %xmm0, %xmm1
                            addps %xmm0, %xmm1
                            movaps %xmm1, %xmm0
                            shufps $85, %xmm1, %xmm0
                            addps %xmm1, %xmm0
                            unpcklps    %xmm0, %xmm0	
                                                                 39
最後に・・・	
  


             40
clangが出力する「unpack1」	
•  一部だけ抜粋(’	
  clang	
  -­‐S	
  -­‐O3	
  -­‐mllvm	
  -­‐vectorize’)	
  
    movsbl     (%rdi), %eax        # *in - %eax
    movd        %eax, %xmm0
    pshufd      $0, %xmm0, %xmm4
    pshufd      $68, %xmm4, %xmm3
    pand        %xmm8, %xmm4
    movl       %eax, %ecx
     ...
    shrq       $2, %r10
    movd       %r10, %xmm0
    punpcklqdq %xmm7, %xmm0
    pand 人類には早すぎる難解なアセンブリが出力された・・・
               %xmm1, %xmm0
    pshufd →nの値でunrollはしないgccに比べてコンサバな最適化	
               $-128, %xmm0, %xmm7
    movss      %xmm6, %xmm7
    movlhps    %xmm7, %xmm5
    shufps     $-30, %xmm7, %xmm5
    movups    %xmm5, (%rsi)       # %xmm5 - dst	

                                                                          41
gcc-­‐4.8	
  vs	
  clang-­‐3.2	
  	
•  「unapack1」の性能比較	
  
•  Intel	
  Core	
  i5-­‐3427@1.8GHzを使用	
  

                       n=15	
          n=16	
     n=32	
      n=64	
          gcc	
    0.051us	
      0.040us	
     0.073us	
   0.152us	
       clang	
     0.105us	
      0.110us	
     0.224us	
   0.446us	
        raQo	
          x2.1	
         x2.7	
      x3.1	
      x3.0	

                                 ベクトル化された状態で約3倍の性能差	




                                                                        42
本日のまとめ	
  


             43
本日のまとめ	
•  clang-­‐v3.2の自動ベクトル化の性能調査	
  
  –  基本的なものは自動的にベクトル化される	
  
  –  処理が複雑になるとgccに対して2~3倍程度の性能差も	
  


•  ‘Vectorizer-­‐Friendly’はまだまだ重要	
  
  –  完全にコンパイラ任せ,というわけには現在いかない	
  
  –  256-­‐bit,	
  512-­‐bit,	
  ...とベクトル長が増えると性能差は拡大	
  
   	
  




                                                            44
本日のまとめ	
•  自動ベクトル化のためのコード規約	
  
 	
  	
  	
  1.	
  ポインタのエイリアスは避ける	
  
 	
  	
  	
  	
  	
   ・必要な個所では__restrict__を付ける	
  
 	
  
 	
  	
  	
  2.	
  ベクトル長の境界に合わせる	
  
 	
  	
  	
  	
  	
  	
  	
  	
  ・__builQn_assume_aligned(X),	
  __aCribute__((aligned(X))の活用	
  
 	
  
 	
  	
  	
  3.	
  Loop内の手作業のinline化は避ける	
  
 	
  	
  	
  	
  	
  	
  	
  ・Loop	
  Vectorizerに任せたほうが賢い	
  
  	
  




                                                                                                    45

Weitere ähnliche Inhalte

Was ist angesagt?

DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるAtsushi KOMIYA
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpsonickun
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたMITSUNARI Shigeo
 
充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろHiroshi Yamashita
 
Parser combinatorってなんなのさ
Parser combinatorってなんなのさParser combinatorってなんなのさ
Parser combinatorってなんなのさcct-inc
 
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようPythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようShinya Takamaeda-Y
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?kwatch
 
研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法Takeshi Yamamuro
 
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...NTT DATA Technology & Innovation
 
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~Takuya Akiba
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装MITSUNARI Shigeo
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例Fixstars Corporation
 
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜Preferred Networks
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介MITSUNARI Shigeo
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safeKumazaki Hiroki
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
 

Was ist angesagt? (20)

DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
llvm入門
llvm入門llvm入門
llvm入門
 
充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろ
 
Parser combinatorってなんなのさ
Parser combinatorってなんなのさParser combinatorってなんなのさ
Parser combinatorってなんなのさ
 
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみようPythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法
 
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
 
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
Boost.SIMD
Boost.SIMDBoost.SIMD
Boost.SIMD
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
CuPy解説
CuPy解説CuPy解説
CuPy解説
 

Ähnlich wie LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)

Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Fixstars Corporation
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングKiwamu Okabe
 
あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)たけおか しょうぞう
 
PEZY-SC2上における倍々精度Rgemmの実装と評価
PEZY-SC2上における倍々精度Rgemmの実装と評価PEZY-SC2上における倍々精度Rgemmの実装と評価
PEZY-SC2上における倍々精度Rgemmの実装と評価Toshiaki Hishinuma
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsKohei KaiGai
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1信之 岩永
 
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみるYasuhiro Yoshimura
 
130710 02
130710 02130710 02
130710 02openrtm
 
第11回 配信講義 計算科学技術特論B(2022)
第11回 配信講義 計算科学技術特論B(2022)第11回 配信講義 計算科学技術特論B(2022)
第11回 配信講義 計算科学技術特論B(2022)RCCSRENKEI
 
Bluetooth通信の 仕組みと活用法紹介
Bluetooth通信の仕組みと活用法紹介Bluetooth通信の仕組みと活用法紹介
Bluetooth通信の 仕組みと活用法紹介Takehiko YOSHIDA
 
Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版Takuya Matsunaga
 
LUT-Network Revision2
LUT-Network Revision2LUT-Network Revision2
LUT-Network Revision2ryuz88
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Emacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェア
Emacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェアEmacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェア
Emacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェアMasaharu IWAI
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPUTakuro Iizuka
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺MITSUNARI Shigeo
 
Osc2012 tokyo fall_home_san_nayamaguti
Osc2012 tokyo fall_home_san_nayamagutiOsc2012 tokyo fall_home_san_nayamaguti
Osc2012 tokyo fall_home_san_nayamagutiNoriyuki Yamaguchi
 

Ähnlich wie LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか) (20)

Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門Halide による画像処理プログラミング入門
Halide による画像処理プログラミング入門
 
HaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミングHaskellではじめるCortex-M3組込みプログラミング
HaskellではじめるCortex-M3組込みプログラミング
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)
 
osoljp 2011.08
osoljp 2011.08osoljp 2011.08
osoljp 2011.08
 
PEZY-SC2上における倍々精度Rgemmの実装と評価
PEZY-SC2上における倍々精度Rgemmの実装と評価PEZY-SC2上における倍々精度Rgemmの実装と評価
PEZY-SC2上における倍々精度Rgemmの実装と評価
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1
 
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
 
130710 02
130710 02130710 02
130710 02
 
第11回 配信講義 計算科学技術特論B(2022)
第11回 配信講義 計算科学技術特論B(2022)第11回 配信講義 計算科学技術特論B(2022)
第11回 配信講義 計算科学技術特論B(2022)
 
Bluetooth通信の 仕組みと活用法紹介
Bluetooth通信の仕組みと活用法紹介Bluetooth通信の仕組みと活用法紹介
Bluetooth通信の 仕組みと活用法紹介
 
Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版Dalvik仮想マシンのアーキテクチャ 改訂版
Dalvik仮想マシンのアーキテクチャ 改訂版
 
LUT-Network Revision2
LUT-Network Revision2LUT-Network Revision2
LUT-Network Revision2
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Emacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェア
Emacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェアEmacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェア
Emacsでの翻訳 - Emacsで訳す、gettextで国際化されたソフトウェア
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺
 
Osc2012 tokyo fall_home_san_nayamaguti
Osc2012 tokyo fall_home_san_nayamagutiOsc2012 tokyo fall_home_san_nayamaguti
Osc2012 tokyo fall_home_san_nayamaguti
 
[DL Hacks]FPGA入門
[DL Hacks]FPGA入門[DL Hacks]FPGA入門
[DL Hacks]FPGA入門
 

Mehr von Takeshi Yamamuro

LT: Spark 3.1 Feature Expectation
LT: Spark 3.1 Feature ExpectationLT: Spark 3.1 Feature Expectation
LT: Spark 3.1 Feature ExpectationTakeshi Yamamuro
 
Quick Overview of Upcoming Spark 3.0 + α
Quick Overview of Upcoming Spark 3.0 + αQuick Overview of Upcoming Spark 3.0 + α
Quick Overview of Upcoming Spark 3.0 + αTakeshi Yamamuro
 
MLflowによる機械学習モデルのライフサイクルの管理
MLflowによる機械学習モデルのライフサイクルの管理MLflowによる機械学習モデルのライフサイクルの管理
MLflowによる機械学習モデルのライフサイクルの管理Takeshi Yamamuro
 
Taming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache SparkTaming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache SparkTakeshi Yamamuro
 
LLJVM: LLVM bitcode to JVM bytecode
LLJVM: LLVM bitcode to JVM bytecodeLLJVM: LLVM bitcode to JVM bytecode
LLJVM: LLVM bitcode to JVM bytecodeTakeshi Yamamuro
 
20180417 hivemall meetup#4
20180417 hivemall meetup#420180417 hivemall meetup#4
20180417 hivemall meetup#4Takeshi Yamamuro
 
An Experimental Study of Bitmap Compression vs. Inverted List Compression
An Experimental Study of Bitmap Compression vs. Inverted List CompressionAn Experimental Study of Bitmap Compression vs. Inverted List Compression
An Experimental Study of Bitmap Compression vs. Inverted List CompressionTakeshi Yamamuro
 
Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題Takeshi Yamamuro
 
VLDB2013 R1 Emerging Hardware
VLDB2013 R1 Emerging HardwareVLDB2013 R1 Emerging Hardware
VLDB2013 R1 Emerging HardwareTakeshi Yamamuro
 
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4Takeshi Yamamuro
 
Introduction to Modern Analytical DB
Introduction to Modern Analytical DBIntroduction to Modern Analytical DB
Introduction to Modern Analytical DBTakeshi Yamamuro
 
SIGMOD’12勉強会 -Session 7-
SIGMOD’12勉強会 -Session 7-SIGMOD’12勉強会 -Session 7-
SIGMOD’12勉強会 -Session 7-Takeshi Yamamuro
 
A x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequencesA x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequencesTakeshi Yamamuro
 
VLDB’11勉強会 -Session 9-
VLDB’11勉強会 -Session 9-VLDB’11勉強会 -Session 9-
VLDB’11勉強会 -Session 9-Takeshi Yamamuro
 
VLDB'10勉強会 -Session 20-
VLDB'10勉強会 -Session 20-VLDB'10勉強会 -Session 20-
VLDB'10勉強会 -Session 20-Takeshi Yamamuro
 

Mehr von Takeshi Yamamuro (20)

LT: Spark 3.1 Feature Expectation
LT: Spark 3.1 Feature ExpectationLT: Spark 3.1 Feature Expectation
LT: Spark 3.1 Feature Expectation
 
Apache Spark + Arrow
Apache Spark + ArrowApache Spark + Arrow
Apache Spark + Arrow
 
Quick Overview of Upcoming Spark 3.0 + α
Quick Overview of Upcoming Spark 3.0 + αQuick Overview of Upcoming Spark 3.0 + α
Quick Overview of Upcoming Spark 3.0 + α
 
MLflowによる機械学習モデルのライフサイクルの管理
MLflowによる機械学習モデルのライフサイクルの管理MLflowによる機械学習モデルのライフサイクルの管理
MLflowによる機械学習モデルのライフサイクルの管理
 
Taming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache SparkTaming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache Spark
 
LLJVM: LLVM bitcode to JVM bytecode
LLJVM: LLVM bitcode to JVM bytecodeLLJVM: LLVM bitcode to JVM bytecode
LLJVM: LLVM bitcode to JVM bytecode
 
20180417 hivemall meetup#4
20180417 hivemall meetup#420180417 hivemall meetup#4
20180417 hivemall meetup#4
 
An Experimental Study of Bitmap Compression vs. Inverted List Compression
An Experimental Study of Bitmap Compression vs. Inverted List CompressionAn Experimental Study of Bitmap Compression vs. Inverted List Compression
An Experimental Study of Bitmap Compression vs. Inverted List Compression
 
Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題
 
20160908 hivemall meetup
20160908 hivemall meetup20160908 hivemall meetup
20160908 hivemall meetup
 
20150513 legobease
20150513 legobease20150513 legobease
20150513 legobease
 
20150516 icde2015 r19-4
20150516 icde2015 r19-420150516 icde2015 r19-4
20150516 icde2015 r19-4
 
VLDB2013 R1 Emerging Hardware
VLDB2013 R1 Emerging HardwareVLDB2013 R1 Emerging Hardware
VLDB2013 R1 Emerging Hardware
 
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
 
Introduction to Modern Analytical DB
Introduction to Modern Analytical DBIntroduction to Modern Analytical DB
Introduction to Modern Analytical DB
 
SIGMOD’12勉強会 -Session 7-
SIGMOD’12勉強会 -Session 7-SIGMOD’12勉強会 -Session 7-
SIGMOD’12勉強会 -Session 7-
 
A x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequencesA x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequences
 
VAST-Tree, EDBT'12
VAST-Tree, EDBT'12VAST-Tree, EDBT'12
VAST-Tree, EDBT'12
 
VLDB’11勉強会 -Session 9-
VLDB’11勉強会 -Session 9-VLDB’11勉強会 -Session 9-
VLDB’11勉強会 -Session 9-
 
VLDB'10勉強会 -Session 20-
VLDB'10勉強会 -Session 20-VLDB'10勉強会 -Session 20-
VLDB'10勉強会 -Session 20-
 

LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)

  • 1. LLVMで遊ぶ   整数圧縮とか、x86向け自動ベクトル化とか 2013/3/30   maropu@x86/64最適化勉強会5     1
  • 2. clang LLVMで遊ぶ   整数圧縮とか、x86向け自動ベクトル化とか 2013/3/30   maropu@x86/64最適化勉強会5     2
  • 3. 本日の概要 •  なんでお前clang(LLVM)の話してんの?   –  RDBMS関連の話題で最近良く扱われるため勉強中   –  今書いている整数圧縮のコードをより高速化したい   •  整数圧縮ライブラリ:  vpacker   –  hCps://github.com/maropu/vpacker   •  clangのx86向け自動ベクトル化   –  SIMDを使用した命令列への自動変換   3
  • 5. DB業界におけるLLVMの利活用 •  SQLによる関係代数の処理をLLVM-­‐JITで改善   –  既存DBのSQL処理系*1は冗長的で非効率   *1SQLコンパイラとSQL実行エンジンのこと Thomas Neumann, Efficiently Compiling Efficient Query Plans for Modern Hardware, Proc. of VLDB’11 5
  • 6. DB業界におけるLLVMの利活用 •  Cloudera  ImpalaにおけるLLVMの利用   •  SQL対応の分散クエリエンジン   •  aggregaQon/join/scanの一部をJITで効率化   •  hCps://github.com/cloudera/impala   引用: http://www.theregister.co.uk/2012/10/24/cloudera_hadoop_impala_real_time_query/ 6
  • 8. vpacker •  32/64-­‐bit整数列を圧縮するライブラリ(C/C++/Java)   –  hCps://github.com/maropu/vpacker     •  前提条件:  正の歪度をもつ整数列を効率的に圧縮   –  大半が小さい値で、稀に大きな値が発生   •  ライブラリの特徴   –  少ないメモリ量で圧縮&展開   –  ILPを考慮した展開処理  -­‐  γ/δ符号と比べて速い   –  動的計画法による圧縮率の最適化   –  ヘッダファイルの読み込みのみで使用可能   8
  • 10. 近年の整数圧縮手法 ~1990’s ~2000’s ~2013 BP/SIMD-BP(2012) γ/δ/Variable-Byte符号 Varint-G8IU(2011) Simple9(2005) Simple16(2009) Simple8b(2010) VSEncoding(2010) PForDelta(2006) OPTPForDelta(2009) SIMD-FastPFor/SimplePFor(2012) 10
  • 11. 近年の整数圧縮手法 ~1990’s ~2000’s ~2013 BP/SIMD-BP(2012) γ/δ/Variable-Byte符号 Varint-G8IU(2011) Simple9(2005) Simple16(2009) Simple8b(2010) -  現在、最速の手法で秒間2000M個整数を展開 -  vpackerは20130330現在の実装で秒間600〜700M程度 VSEncoding(2010) PForDelta(2006) OPTPForDelta(2009) SIMD-FastPFor/SimplePFor(2012) 11
  • 12. vpacker  –  内部構造   •  圧縮データのバイナリフォーマット   –  前半のディスクリプタ部と圧縮したデータ部で構成   ディスクリプタ部(desc) 圧縮データ部(in) 1-byteのディスクリプタの列 圧縮された整数データ 後半の圧縮したデータが どのように格納されているかを記録 12
  • 13. vpacker  –  内部構造   •  圧縮データのバイナリフォーマット   ディスクリプタ部(desc) 圧縮データ部(in) 1-byteのデータに固定長1-bitで8個の整数が格納 void unpack1_8(const char *in, uint32_t *out) { *out++ = in[0] & 0x01; *out++ = (in[0] >> 1) & 0x01; *out++ = (in[0] >> 2) & 0x01; ... *out++ = (in[0] >> 7) & 0x01; } 13
  • 14. vpacker  –  内部構造 •  圧縮データのバイナリフォーマット   2-byteのデータに固定長2-bitで8個の整数が格納 ディスクリプタ部(desc) 圧縮データ部(in) 1-byteのデータに固定長1-bitで8個の整数が格納 void unpack2_8(const char *in, uint32_t *out) { *out++ = in[0] & 0x03; *out++ = (in[0] >> 2) & 0x03; *out++ = (in[0] >> 4) & 0x03; ... *out++ = (in[1] >> 6) & 0x03; } 14
  • 15. vpacker  –  内部構造 •  復元処理の動作概要   2-byteのデータに固定長2-bitで8個の整数が格納 ディスクリプタ部(desc) 圧縮データ部(in) 1-byteのデータに固定長1-bitで8個の整数が格納 while (1) { switch (*desc++) { case 1-bitで8個の整数を展開: unpack1_8(in, out); break; case 2-bitで8個の整数を展開: unpack2_8(in, out); break; ... } -  VMのインタプリタ的な処理の流れ } -  descは1-byteのため最大256分岐(分岐数は設計による) 15
  • 16. vpacker  –  内部構造 •  LLVM-­‐JITを用いてwhile-­‐switchを軽量化   –  共通する復元処理をまとめることでjmp命令を除去   ディスクリプタ部(desc) 圧縮データ部(in) 「前提条件」より大半の復元処理は 一部の関数に集中 while (1) { switch (*desc++) { case 1-bitで8個の整数を展開: unpack1_8(in, out); break; case 2-bitで8個の整数を展開: unpack2_8(in, out); break; ... } } 16
  • 17. vpacker  –  内部構造 •  呼び出しが集中している関数を高速化   –  基本はSIMDを利用したデータ並列性の向上   ディスクリプタ部(desc) 圧縮データ部(in) 呼び出しが集中している関数を高速化 while (1) { switch (*desc++) { case 1-bitで8個の整数を展開: unpack1_8(in, out); break; case 2-bitで8個の整数を展開: unpack2_8(in, out); break; ... } } 17
  • 18. gcc(v4.8)の自動ベクトル化 •  この関数*1ってどんな機械語に変換されるの?   –  処理に依存関係が無く,ベクトル化しやすそうな印象   void unpack1(const char *in, uint32_t *out, int n) { for (int i = 0; i < n; i++) { *out++ = in[0] & 0x01; *out++ = (in[0] >> 1) & 0x01; *out++ = (in[0] >> 2) & 0x01; ... *out++ = (in[0] >> 7) & 0x01; } } *1 現実に即して,ループ回数(n)を指定できるように変更しました 18
  • 19. gcc(v4.8)の自動ベクトル化 •  この関数ってどんな機械語に変換されるの?   –  処理に依存関係が無く,ベクトル化しやすそうな印象   void unpack1(const char *in, uint32_t *out, int n) { for (int i = 0; i < n; i++) { *out++ = in[0] & 0x01; *out++ = (in[0] >> 1) & 0x01; *out++ = (in[0] >> 2) & 0x01; ... *out++ = (in[0] >> 7) & 0x01; } } 重要) コンパイルする前に自動ベクトル化されやすいように前処理 19
  • 20. gcc(v4.8)の自動ベクトル化 •  この関数ってどんな機械語に変換されるの?   –  処理に依存関係が無く,ベクトル化しやすそうな印象   void unpack1(const char *in, uint32_t *out, int n) { for (int i = 0; i < n; i++) { for (int j = 0; j < 8; j++) *out++ = (*in >> j) & 0x01; in++; } } gccの場合、SLP(Superword-Level Parallelism)による最適化より Loop Vectorizerに任せたほうが良いらしいです 20
  • 21. gcc(v4.8)の自動ベクトル化 •  この関数ってどんな機械語に変換されるの?   –  処理に依存関係が無く,ベクトル化しやすそうな印象   void unpack1(const char * __restrict__ in, uint32_t * __restrict__ out, int n) { for (int i = 0; i < n; i++) { for (int j = 0; j < 8; j++) *out++ = (*in >> j) & 0x01; in++; } } __restrict__を付与してin/outを呼び出し側で16Bにアライメント 21
  • 22. gcc(v4.8)の自動ベクトル化 •  一部だけ抜粋  &  並び替え(’gcc  -­‐O3’)   movdqu (%r9), %xmm1 // in - %xmm1 pxor %xmm2, %xmm2 pcmpgtb %xmm1, %xmm2 movdqa %xmm1, %xmm3 punpckhbw %xmm2, %xmm1 punpcklbw %xmm2, %xmm3       pxor %xmm2, %xmm2 movdqa %xmm3, %xmm4 pcmpgtw %xmm3, %xmm2 punpcklwd %xmm2, %xmm4 movdqa %xmm4, %xmm5 pand %xmm0, %xmm5 // %xmm1=[0x01, 0x01, 0x01, 0x01] .... 22
  • 23. gcc(v4.8)の自動ベクトル化 •  一部だけ抜粋    並び替え(’gcc  -­‐O3’)   movdqu (%r9), %xmm1 // in - %xmm1 pxor %xmm2, %xmm2 pcmpgtb %xmm1, %xmm2 movdqa %xmm1, %xmm3 punpckhbw %xmm2, %xmm1 punpcklbw %xmm2, %xmm3 バイトからワードに符号拡張       pxor %xmm2, %xmm2 movdqa %xmm3, %xmm4 pcmpgtw %xmm3, %xmm2 punpcklwd %xmm2, %xmm4 ワードからダブルワードに符号拡張 movdqa %xmm4, %xmm5 pand %xmm0, %xmm5 // %xmm1=[0x01, 0x01, 0x01, 0x01] .... 0x01でマスクして展開処理完了 23
  • 24. gcc(v4.8)の自動ベクトル化 •  一部だけ抜粋    並び替え(’gcc  -­‐O3’)   movdqu (%r9), %xmm1 // in - %xmm1 pxor %xmm2, %xmm2 pcmpgtb %xmm1, %xmm2 movdqa %xmm1, %xmm3 punpckhbw %xmm2, %xmm1 punpcklbw %xmm2, %xmm3 バイトからワードに符号拡張       pxor %xmm2, %xmm2 movdqa %xmm3, %xmm4 pcmpgtw %xmm3, %xmm2 punpcklwd %xmm2, %xmm4 ワードからダブルワードに符号拡張 ‘n 15’で分岐させてLoopを全てinline化するアグレッシブな最適化 movdqa %xmm4, %xmm5 →’n = 15’はベクトル化されていないパスに分岐 pand %xmm0, %xmm5 // %xmm1=[0x01, 0x01, 0x01, 0x01] .... 0x01でマスクして展開処理完了 24
  • 26. clangと自動ベクトル化 •  LLVM上に実装されたC/C++用フロントエンド   –  hCp://clang.llvm.org/index.html   •  Auto-­‐VectorizaQon  in  LLVM   –  hCp://llvm.org/docs/Vectorizers.html   •  Linpackを用いた性能評価   –  with  loop  vectorizaQon  at  -­‐O3  running  on  a  Sandybridge   自動ベクトル化の有無で 性能差が3倍程度! 26
  • 27. clangにおける2種類のVectorizer •  Basic-­‐Block(BB)  Vectorizer  –  SLP  in  gcc     –  v3.1で”  -­‐mllvm  –vectorize”として導入   –  最適化の対象が「Basic  Block」   –  歴史的に実装されたのはコチラが先   •  Loop  Vectorizer   –  v3.2でようやく”  -­‐mllvm  –vectorize-­‐loops”として導入   –  「Unroll+BB  Vectorizer」にLoop間依存解析を加えたもの   –  自動ベクトル化の制約(v3.2のReleaseNotesより)   •  Loop枚のカウントは”1”のみ   •  InducQon変数は一番内側のLoopのみ使用可能   27
  • 28. clangの自動ベクトル化パラメータ •  clang-­‐v3.2を利用(2013/3/30現在最新)   –  デフォルトで自動ベクトル化は全てOFF   –  v3.3からLoop  Vectorizerはデフォルトに     •  -­‐mllvm  –vectorize,  -­‐mllvm  –vectorize-­‐loops   –  -­‐O2/-­‐O3との併用が必要   –  -­‐Osはコード増加が発生しない場合に適用   •  -­‐mllvm  –bb-­‐vectorize-­‐aligned-­‐only   –  アラインされたstore/loadのみを最適化に使用   •  -­‐mllvm  –force-­‐vector-­‐width=X   –  最適化で使用するベクトル要素数をXで指定   28
  • 29. その他の補助パラメータ •  -­‐mllvm  –unroll-­‐allow-­‐parQal   –  Loop内の部分的なUnrollを可能に   •  -­‐mllvm  –unroll-­‐runQme   –  実行時にLoopを数えてUnroll可能に   •  -­‐funsafe-­‐math-­‐opQmizaQons,  -­‐ffast-­‐math   –  浮動小数点演算にIEEE/ISO仕様外の最適化を適用   •  他の関連するパラメータは以下の資料が詳しい   –  Auto-­‐vectorizaQon  with  LLVM   –  hCp://llvm.org/devmtg/2012-­‐04-­‐12/Slides/Hal_Finkel.pdf     29
  • 30. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.1#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     void test1(float * __restrict__ a, float * __restrict__ b, int n) { for (int i = 0; i n; i++) a[i] += b[i]; } 30
  • 31. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.1#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     %rdiと%rsiは16Bに揃えてあるのに .LBB0_2: なぜかmovapsに変換されない? movups 16(%rdi,%rax,4), %xmm1 movups 16(%rsi,%rax,4), %xmm0 addps %xmm1, %xmm0 movups (%rdi,%rax,4), %xmm1 movups (%rsi,%rax,4), %xmm2 movups %xmm0, 16(%rdi,%rax,4) addps %xmm1, %xmm2 movups %xmm2, (%rdi,%rax,4) addq $8, %rax cmpq %rax, %rcx jne .LBB0_2 31
  • 32. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.2#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     void test2(float * __restrict__ a, float * __restrict__ b, int n) { for (int i = 0; i n; i += 2) a[i] += b[i]; } 32
  • 33. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.2#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     .LBB0_2: movss (%rsi,%rax,4), %xmm0 addss (%rdi,%rax,4), %xmm0 movss %xmm0, (%rdi,%rax,4) addq $2, %rax cmpl %edx, %eax jl .LBB0_2 33
  • 34. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.3#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     void test3(float * __restrict__ a, float * __restrict__ b, int n) { for (int i = 0; i n; i += 1) { for (int j = 0; j SIZE; j++) a[i * SIZE + j] += b[i * SIZE + j]; } } 34
  • 35. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.3#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     .LBB1_22: # = The Inner Loop movups (%rbx), %xmm2 movups 16(%rbx), %xmm1 movups (%rax), %xmm0 movups 16(%rax), %xmm3 addps %xmm2, %xmm0 addps %xmm1, %xmm3 movups %xmm3, 16(%rbx) movups %xmm0, (%rbx) addq $32, %rbx addq $32, %rax addq $-8, %rdi jne .LBB1_22 35
  • 36. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.4#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     float test4(float * __restrict__ a, int n) { float S = 0.0; for (int i = 0; i n; i += 1) S += a[i]; return S; } 36
  • 37. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.4#   –  clang  -­‐O3  -­‐mllvm  -­‐vectorize-­‐loops     .LBB0_1: addss (%rdi), %xmm0 addq $4, %rdi decl %esi jne .LBB0_1 浮動小数点演算は結合則が成り立たないため、こういう命令列に →clangにも’-ffast-math’があるが、出力する命令は同じだった 37
  • 38. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.4#   –  gcc  -­‐O3  -­‐ffast-­‐math     .L33: addps (%rax), %xmm0 addq $16, %rax cmpq %rdx, %rax jne .L33 movaps %xmm0, %xmm1 movhlps %xmm0, %xmm1 addps %xmm0, %xmm1 movaps %xmm1, %xmm0 shufps $85, %xmm1, %xmm0 addps %xmm1, %xmm0 unpcklps %xmm0, %xmm0 38
  • 39. WriQng  Vectorizer-­‐Friendly  Code  in  clang     •  example.4#   –  gcc  -­‐O3  -­‐ffast-­‐math   ベクトル加算して   .L33: addps (%rax), %xmm0 addq $16, %rax cmpq %rdx, %rax jne .L33 水平加算 movaps %xmm0, %xmm1 movhlps %xmm0, %xmm1 addps %xmm0, %xmm1 movaps %xmm1, %xmm0 shufps $85, %xmm1, %xmm0 addps %xmm1, %xmm0 unpcklps %xmm0, %xmm0 39
  • 41. clangが出力する「unpack1」 •  一部だけ抜粋(’  clang  -­‐S  -­‐O3  -­‐mllvm  -­‐vectorize’)   movsbl (%rdi), %eax # *in - %eax movd %eax, %xmm0 pshufd $0, %xmm0, %xmm4 pshufd $68, %xmm4, %xmm3 pand %xmm8, %xmm4 movl %eax, %ecx ... shrq $2, %r10 movd %r10, %xmm0 punpcklqdq %xmm7, %xmm0 pand 人類には早すぎる難解なアセンブリが出力された・・・ %xmm1, %xmm0 pshufd →nの値でunrollはしないgccに比べてコンサバな最適化 $-128, %xmm0, %xmm7 movss %xmm6, %xmm7 movlhps %xmm7, %xmm5 shufps $-30, %xmm7, %xmm5 movups %xmm5, (%rsi) # %xmm5 - dst 41
  • 42. gcc-­‐4.8  vs  clang-­‐3.2   •  「unapack1」の性能比較   •  Intel  Core  i5-­‐3427@1.8GHzを使用   n=15 n=16 n=32 n=64 gcc 0.051us 0.040us 0.073us 0.152us clang 0.105us 0.110us 0.224us 0.446us raQo x2.1 x2.7 x3.1 x3.0 ベクトル化された状態で約3倍の性能差 42
  • 44. 本日のまとめ •  clang-­‐v3.2の自動ベクトル化の性能調査   –  基本的なものは自動的にベクトル化される   –  処理が複雑になるとgccに対して2~3倍程度の性能差も   •  ‘Vectorizer-­‐Friendly’はまだまだ重要   –  完全にコンパイラ任せ,というわけには現在いかない   –  256-­‐bit,  512-­‐bit,  ...とベクトル長が増えると性能差は拡大       44
  • 45. 本日のまとめ •  自動ベクトル化のためのコード規約        1.  ポインタのエイリアスは避ける             ・必要な個所では__restrict__を付ける          2.  ベクトル長の境界に合わせる                  ・__builQn_assume_aligned(X),  __aCribute__((aligned(X))の活用          3.  Loop内の手作業のinline化は避ける                ・Loop  Vectorizerに任せたほうが賢い       45