SlideShare ist ein Scribd-Unternehmen logo
1 von 76
Downloaden Sie, um offline zu lesen
1/76	



          短距離古典分子動力学計算の
            高速化と大規模並列化	

                             渡辺宙志
                          東京大学物性研究所



                        Outline
               1.  チューニング、その前に
               2.  計算機の仕組みと高速化
               3.  並列化
               4.  大規模計算でなにができるか
               5.  まとめ
Dec. 13, 2012「第6回分子シミュレーションスクール」@岡崎カンファレンスホール	
                                                  University of Tokyo
2/76	




チューニング、その前に	




                University of Tokyo
3/76	
           チューニング、その前に (1/5)


A fast runner is not a good soccer player.	
                             H. Watanabe, 2012	




                                            University of Tokyo
4/76	
     チューニング、その前に (2/5)

最適化の第一法則:最適化するな


最適化の第二法則(上級者限定):まだするな

                Michael A. Jackson, 1975	




                                   University of Tokyo
5/76	
        チューニング、その前に (3/5)

なぜ最適化するのか?	

 プログラムの実行時間を短くするため	

なぜ実行時間を短くしたいのか?	

  計算結果を早く手に入れるため	

なぜ計算結果を早く手にいれたいのか?	

  論文を早く書くため ← ここがとりあえずのゴール	

最適化、並列化をする際には、必ず「いつまでに論文執筆まで
持って行くか」を意識すること。だらだらと最適化にこだわらない。	


                               University of Tokyo
6/76	
      チューニング、その前に (4/5)

Q. 最適化、並列化でもっとも大事なことは何か?




A. バグを入れないこと	
 通常、プログラミングにおいて最も時間のかかるプロセスは
 デバッグだから	




                          University of Tokyo
7/76	
              チューニング、その前に (5/5)

バグを入れない方法	
  いろいろあるが、特に以下の二つの方法が有効
  ・単体テスト
  ・sort + diff デバッグ	

単体テスト	
 ・テストしようとしている部分だけを切り出す
 ・その部分だけでコンパイル、動作するような最低限のインターフェース
 ・最適化、並列化する前と後で結果が一致するかを確認する
 ・本番環境でテストしない	


sort + diff デバッグ	
  ・print文デバッグの一種
  ・出力情報を保存し、sortしてからdiffを取る
  ・単体テストと組み合わせて使う	

                                     University of Tokyo
8/76	
          sort + diff デバッグの例1 - 粒子対リスト作成 (1/3)	
ペアリストとは?	

  ・相互作用距離(カットオフの距離)以内にある粒子対のリスト	
  ・どの粒子同士が近いか?という情報	
  ・全粒子対についてチェックすると      	
  ・高速に粒子対を作成する方法 → グリッド探索	

グリッド法	
  ・空間をグリッドに切り、その範囲に存在する粒子を登録する	


  排他的グリッド(Exclusive Grid )法	
   非排他的グリッド(Non-Exclusive Grid )法	


              一つのグリッドに粒子一つ	
                一つのグリッドに複数粒子	

              ・短距離相互作用	
                    ・長距離相互作用	
              ・二次元	
                        ・三次元	
              ・高密度	
                        ・低密度	




                                                         University of Tokyo
9/76	
         sort + diff デバッグの例1 - 粒子対リスト作成 (2/3)	

ポイント	
 O(N^2)法は、計算時間はかかるが信頼できる
 O(N)法とO(N^2)法は、同じconfigurationを与えられたら、
 同じペアリストを作るはず
手順	
 初期条件を作るルーチンを作る
 ペアリスト作成ルーチンを作り、コンパイル、実行できるようにする (単体テスト)
 O(N)とO(N^2)ルーチンに初期条件を与え、作成したペアリストをダンプする
       ダンプ方法:作成された粒子対の、番号が若い方を左にして、一行に1ペア
  O(N)とO(N^2)でリストの順番が異なるはずなのでsortする
  $ ./on2code | sort > o2.dat
  $ ./on1code | sort > o1.dat
  diffを取る
  $ diff o1.dat o2.dat
  結果が正しければdiffは何も出力しない

 いきなり本番環境に組み込んで時間発展、などとは絶対にしない	
                                              University of Tokyo
10/76	
         sort + diff デバッグの例1 - 粒子対リスト作成 (3/3)	

並列版のデバッグ	
 ペアリスト作成の並列化
 ・はじっこの粒子が正しく渡されているか?
 ・周期境界条件は大丈夫か?

手順	

 初期条件を作るルーチンを作る
 並列版と非並列版のペアリスト作成ルーチンを作る
 非並列版はそのままペアリストをダンプ
 並列版は「若い番号の粒子が自分の担当の粒子」
 であるときだけダンプ
 sort + diffで一致を確認する
ポイント	
 まず、並列版と非並列版両方O(N^2)で試す
 →粒子の受け渡しがバグっているのか、O(N)の並列化が間違っているのか
 区別するため	
                 一度に複数の項目を同時にテストしない	
         University of Tokyo
11/76	
         sort + diff デバッグの例2 - 粒子情報送信	
端の粒子の送り方	
 ナイーブな送り方	

                正しく情報が送られているかをチェックする

                →粒子の情報を送る前と、送ったあとそれぞれで
                全粒子座標を出力してsort+diff




通信方法を減らした送り方 (もらった粒子をさらに転送することで斜め通信をなくす)	




                                          University of Tokyo
12/76	
          チューニングをする前に	

・新しい機能を追加するたびに単体テストをする
・高速化をためしたら、かならず単体テストをする
   単体テストとは、ミクロな情報がすべて一致するのを確認することであ
   り、エネルギー保存など、マクロ量のチェックは単体テストではない

・時間はかかるが信用できる方法と比較する
 「確実にここまでは大丈夫」という「砦」を築いて行く作業
・複数の機能を一度にテストしない
・特に並列プログラムはバグを入れるととても大変なので、事前に
 十分なデバッグが必要	

   デバッグとは、入れたバグを取ることではなく、そもそもバ
   グを入れないことである


                               University of Tokyo
13/76	




計算機の仕組み	




            University of Tokyo
14/76	
         計算機の仕組みと高速化	
高速化とは何か?	

ここでは「アルゴリズムを変えずに、実装方法によって
実行時間を短くする方法」と定義	
 → アルゴリズムレベルの最適化は終了していることを想定	

遅いアルゴリズムを実装で高速化しても意味がないので、
十分にアルゴリズムレベルで最適化が済んでいることを確認すること	

実装レベルの高速化とは何か?	

 「コンパイラや計算機にやさしいコードを書く事」	
                   ※やさしい=理解しやすい、向いている	


そのためには、計算機の仕組みを理解しておかなければならない	

                                  University of Tokyo
15/76	
              プログラム階層	

ノード間通信
(並列化)	
               Network

メモリ転送
(キャッシュ最適化)	
 Memory    Memory   Memory


CPUコア
(チューニング)     Cache     Cache    Cache
SIMD化、if分岐削除
              CPU       CPU      CPU

          この中で最も重要なのはメモリ転送

                                  University of Tokyo
16/76	
                                         記憶階層	

                              Register
       FPU
                              Register
                              Register
                                           L1     L2   Memory
       FPU                    Register

 Floating Processing Unit	
                              CPU
・計算はレジスタ上で行う
・レジスタにのせられた情報はFPUに渡され、レジスタにかえってくる
・メモリアクセスで大事なのは、バンド幅とレイテンシ
Latency	
  CPUにデータを要求されてから、レジスタに届くまでのサイクル数
  ・L1キャッシュで数サイクル、L2で10 20サイクル、主記憶は 数百サイクル	
Bandwidth	
   CPUにデータが届き始めてからのデータ転送速度
   絶対値(GB/s)よりも、計算速度との比(B/F)の方が良く使われる	
                                                          University of Tokyo
17/76	
                      Byte / Flop	
Byte/Flop	
  データ転送速度(Byte/s) と計算速度 (FLOPS)の比。略してB/F。
  値が大きいほど、計算速度に比べたデータ転送能力が高い。

                      典型的には B/F = 0.1∼0.5	

B/Fの意味	
   一つの倍精度実数(64bit)の大きさ = 8 Byte
   計算するには、最低二つの倍精度実数が必要 = 16 Byte
   最低でも一つの倍精度実数を書き戻す必要がある = 8 Byte.
   例えば一回掛け算をして、その結果をメモリに書き戻すと、24Byteの読み書きが発生
   B/F = 0.5 のマシンでは、24バイトの読み書きの間に48回計算ができる


         B/Fが0.5の計算機では、C = A*Bという単純な計算をくりかえすと
         ピーク性能の2%ほどしか出せず、ほとんど時間CPUが遊ぶ

              キャッシュ効率が性能に直結する
                                              University of Tokyo
18/76	
                 仮想メモリとページング (1/2)
Virtual Memory
 現在の一般的なOSでは、メモリをページと呼ばれる仮想記憶で管理する。

  ハードディスク	
           仮想メモリ       物理メモリ	
                      (論理メモリ)	




                                            連続配列が、物理メモリ内
                                            では不連続に割り当てら
                                            れてるかもしれない	
   一部がハードディスクにスワップさ
   れているかもしれない	

仮想メモリを使う理由
・不連続なメモリ空間を論理的には連続に見せることができる
 仮想メモリなしでは、メモリに余裕があっても連続領域が取れない場合にメモリ割り当てができない
・スワッピングが可能になる
 記憶容量としてハードディスクも使えるため、物理メモリより広い論理 メモリ空間が取れる。


 論理メモリと実メモリの対応が書いてあるのがTLB (テキスト参照)	
                                                  University of Tokyo
19/76	
                    仮想メモリとページング (2/2)
数値計算で何が問題になるか?
 F90のallocateや、Cでnew、mallocされた時点では物理メモリの
 割り当てがされていない場合がある	

  real*8, allocatable :: work(:)
  allocate (work(10000))           この時点では予約だけされて、まだ物理アドレスが割り当てられない	
  do i=1, 10000
   work(i) = i                     はじめて触った時点で、アドレスがページ単位で割り当てられる
  end do	
                         (First touch の原則)	

よくある問題:
最初に馬鹿でかい配列を動的に確保しているプログラムの初期化がすごく遅い
 地球シミュレータからT2Kへの移植で問題になることが多い。OSがLinuxである
 京でも発生する

解決策:
 メモリを静的に確保する(?)
 mallocではなくcallocを使う (Fortranではどうやるのか知りません)
 メモリを確保した直後、ページ単位で全体を触っておく

                           まぁ、そういうこともあると覚えておいてください
                                                           University of Tokyo
20/76	
                             NUMA (1/2)
NUMAとは
 非対称メモリアクセス(Non-Uniform Memory Access)の略
 CPUにつながっている物理メモリに近いメモリと遠いメモリの区別がある
 京コンピュータはNUMAではないが、物性研System BはNUMA

             Fast access	


         Memory	
                              Memory	
         Memory	
        CPU	
 QPI	
 CPU	
     Memory	
         Memory	
                              Memory	


                                 Slow access
                                 特にlatency	




                                                          University of Tokyo
21/76	
                              NUMA (2/2)
数値計算で何が問題になるか?
OpenMPでCPUをまたぐ並列化をする際、初期化を適当にやると
作業領域がコアから遠い物理メモリに割り当てられてしまう	
       Touch	
                 CORE	
   CORE	
            CORE	
   CORE	


                                    QPI	
                 CORE	
   CORE	
            CORE	
   CORE	




          OpenMPのスレッドを作る前に配列を初期化
           →root プロセスの近くにメモリ割り当て
          その後OpenMPでスレッド並列
           →遠いメモリをアクセス(遅い)	
解決策:
 スレッドに対応する物理コアに近いところにメモリが割り当てられるように、スレッドごと
に配列を用意した上、OpenMPでスレッド並列化した後にtouchとか


                                   詳しくはNUMA最適化でググれ
                                                              University of Tokyo
22/76	
                          CPU (1/2)	
RISCと CISC	
 世の中のCPUアーキテクチャは大別して RISC型とCISC型の二種類
 CISC:
  ・比較的複雑な命令セット
  ・if分岐などに強い (Out of order 実行)
  ・Intel Xeon, AMD Opteronなど。
 RISC:
  ・比較的単純な命令セット
  ・行列演算などに強い
  ・IBM Power, SPARCなど (「京」はSPARC VIIIfx)
                RISCでOoOだったりするので、現在はあまり意味のある区別ではない。
                要するに「Intel系か、それ以外か」という区別	


マルチコアとSIMD化	
  最近のCPUはほぼマルチコア化とSIMD化で性能をかせいでいる	
  ・マルチコアで性能を出すには、キャッシュとメモリの構造を把握する必要あり	
  ・京(8コア) FX10 (16コア) IBM POWER6 (32コア)、SGI Altix ICE(4コア*2)
  ・SIMDについては後述	


                                                           University of Tokyo
23/76	
                     CPU (2/2)	
ゲーム機とCPU
第六世代	
DC SH-4
PS2 MIPS (Emotion Engine), VLIW
GC IBM PowerPC カスタム (Gekko)
Xbox Intel Celeron (PenIII ベース)

第七世代	
Wii IBM PowerPC カスタム	
Xbox 360 IBM PowerPC カスタム	
PS3 IBM Cell 3.2	




                                   University of Tokyo
24/76	
            レイテンシとパイプライン (1/3)	
レイテンシとは	
命令が発行されてから、値が帰ってくるまでのクロック数	
 fadd   fp2,fp0,fp1   # fp2 ← fp0 + fp1
 fadd   fp4,fp2,fp3   # fp4 ← fp2 + fp3

                                          パイプライン	
          fadd   fp2,fp0,fp1           計算開始
                                        計算中
                                        計算中
                                        計算中
                                        計算中
                                        計算中
                                    計算終了 (fp2使用可)
          fadd   fp4,fp2,fp3
                                                     University of Tokyo
25/76	
                     レイテンシとパイプライン (2/3)	
パイプラインとは	
 浮動小数点の加算、減算、掛け算といった計算を流れ作業で行う仕組み
fadd    fp2,fp0,fp1 (A)
fadd    fp5,fp3,fp4 (B)
fadd    fp8,fp3,fp7 (C)

       (A) 1                (A) 計算開始	
       (B) 1 (A) 2
       (C) 1 (B) 2 (A) 3
       (D) 1 (C) 2 (B) 3 (A) 4
       (E) 1 (D) 2 (C) 3 (B) 4 (A) 5
       (F) 1   (E) 2 (D) 3 (C) 4 (B) 5 (A) 6   (A) 計算終了	
                           (D) 4 (C) 5 (B) 6   (B) 計算終了	
                                                                時間	
ここだけ見ると、6クロックかかる処理を同時に6つ処理している
→ 一クロックで一回の計算ができているように見える (レイテンシの隠蔽)
これを「スループット が1」と呼ぶ	
                                                            University of Tokyo
26/76	
           レイテンシとパイプライン (3/3)	
パイプライン数	
 一般的にはパイプラインは2本	
 Load/Storeも出せる場合は、IPCは最大4
                ※

  パイプライン	
                    パイプライン	

                faddd   fp2,fp0,fp1      計算開始

    計算開始       fmuld    fp3,fp1,fp4       計算中

    計算中                                   計算中

    計算中                                   計算中

    計算中                                   計算中

    計算中                                   計算中

    計算中                               計算終了 (fp2使用可)

    計算終了


実質的に、1クロックで二つの計算が可能
→ 2GHz × 2 = 4 GFLOPS	

                                                      University of Tokyo
27/76	
            積和(差)命令 fmaddd, fmsubd	
積和、積差	
 積和   X = A*B+C
 積差   Y = A*B-C	
アセンブラでは	
 fmaddd fp0,fp1,fp2,fp3    # fp0 ← fp1*fp2+fp3
 fmsubd fp0,fp1,fp2,fp3   # fp0 ← fp1*fp2+fp3

乗算一つ、加減算一つ、あわせて二つが(実質)1クロックで実行される。
そのパイプラインが二つあるので、あわせて1クロックで4つの演算
→ 2GHz × 4 = 8 GFLOPS	



             アセンブリにfmaddd,fmsubdが
             ずらずら並んでいなければダメ	
                                             University of Tokyo
28/76	
                      SIMD	
SIMDとは	
 Single Instruction Multiple Data の略。通称シムド。
 ベクトル命令のようなもの。
 独立な同じ計算を同時に行う。	
積和、積差のSIMD	
 fmadd,s X1 = A1*B1+C1 , X2 = A2*B2+C2 を同時に実行
 fmsub,s X1 = A1*B1-C1 , X2 = A2*B2-C2 を同時に実行

  fmadd,sは、一つで4個の浮動小数点演算を行う。
  「京」はこれが同時に二つ走る
  4 * 2 * 2 GHz = 16GFlops (ピーク性能)	
            アセンブリにfmaddd,s fmsubd,sが
             ずらずら並んでいなければダメ	
                                              University of Tokyo
29/76	
                パイプラインのイメージ	
     A                     A
     +B	
                  +B	
    A-B	
                   A*B-C	
                            A1*B1+    A2*B2+
     A*B+C	
                              C1	
      C2	
                            A1*B1+    A2*B2+
    A-B	
                              C1	
      C2	
     A1*B1+    A2*B2+
                            A*B+C	
       C1	
      C2	
     A*B-C	
               A-B	

・幅が4、長さが6のベルトコンベアがある
・それぞれには、大きさ1、2、4の荷物を流せるが、同時に一つしか置けない
・ピーク性能比=ベルトコンベアのカバレージ
・ピーク性能を出す=なるべくおおきさ4の荷物を隙間無く流す
 (Intel系の命令パイプラインはやや異なる)            University of Tokyo
30/76	
          計算機の仕組みのまとめ
・期待する性能がでない時、どこが問題かを調べるのに
 計算機の知識が必要 (特にメモリアクセス)
・積和のパイプラインを持つCPUで性能を出すためには、	
 独立な積和演算がたくさん必要
・SIMDを持つCPUで性能を出すためには、
 独立なSIMD命令がたくさん必要
 → 京やFX10では、独立な積和のSIMD命令がたくさん必要	

     アセンブリを読みましょう	
     変にプロファイラと格闘するより直接的です	


      (-S 付きでコンパイルし、 fmadd,sなどでgrep)	


                                         University of Tokyo
31/76	




メモリアクセス最適化	




               University of Tokyo
32/76	
                 メモリ最適化(1/2)
セル情報	
相互作用粒子を探すさい、空間をセルに分割し、それぞれに登録する
どの空間に粒子が存在するかを多次元配列で実装すると効率が悪い	
int GridParticleNumber[GridX][GridY];
int GridParticleIndex[GridX][GridY][GridMax];

       一次元配列実装	

                                      O(N) Partial Sort

                                       キャッシュ効率向上
                                       レイテンシ	




                                                University of Tokyo
33/76	
              メモリ最適化(2/2)
相互作用ペアリスト
短距離相互作用の場合、相互作用ペアリストを使う (Bookkeeping 法)


何も考えずに実装すると・・・
 メモリ空間をランダムアクセスする(キャッシュ効率低下)
 二つ分の粒子の情報をレジスタに持ってくる必要がある(要求バンド幅増大)
    相互作用相手でソートする




相互作用粒子の一方がレジスタに載る
データの読み込みが半分になる
                                          University of Tokyo
34/76	
        キャッシュ最適化 (1/2)
空間ソート




時間発展を続けると、空間的には近い粒子が、メモリ上では
遠くに保存されている状態になる → ソート	
                          University of Tokyo
35/76	
           キャッシュ最適化(2/2)
空間ソートの効果

                             ソートあり	




            L2 Cache   L3 Cache
            (256 KB)   (8 MB) ソートなし	



               粒子数	
 ソートなし:粒子数がキャッシュサイズをあふれる度に性能が劣化する
 ソートあり:性能が粒子数に依存しない
                                        University of Tokyo
36/76	
            メモリ管理のまとめ	
CPUチューニングの前にメモリアクセスのチェックを
とにかくキャッシュにのせる
連続アクセスにする (Partial Sortが有効)
メモリアクセスの最適化は、計算機を選ばないことが多い
 (CPUチューニングはアーキテクチャに強く依存する)	

並列化の前にメモリアクセスの最適化をする
・メモリアクセスの最適化をすると、データの持ち方が変わる
 →並列化の通信ルーチンが強く影響を受ける
・逆にNUMA最適化など、並列化をにらんだデータ構造を持つ必要もある
 →要するになんども組み直す必要があるということ	



 必要なデータがほぼキャッシュに載っており、CPUの
 計算待ちがほとんどになって初めてCPUチューニングへ	


                                University of Tokyo
37/76	




CPUチューニング	




              University of Tokyo
38/76	
         CPUチューニング	

  PCで開発したコード、スパコンでの実行性能が
  すごく悪いんですが・・・




     それ、条件分岐が原因かもしれません。




開発ではIntel系のCPUを使うことが多く、スパコンは
別のRISCタイプアーキテクチャを使うことが多い	


                               University of Tokyo
39/76	
                                 条件分岐コスト (1/2)	
               条件分岐なし	
                                条件分岐あり	
void                                               void
calcforce(void){                                   calcforce(void){
  for(int i=0;i<N-1;i++){                            for(int i=0;i<N-1;i++){
    for(int j=i+1;j<N;j++){                            for(int j=i+1;j<N;j++){
      const double dx = q[j][X] - q[i][X];               const double dx = q[j][X] - q[i][X];
      const double dy = q[j][Y] - q[i][Y];               const double dy = q[j][Y] - q[i][Y];
      const double dz = q[j][Z] - q[i][Z];               const double dz = q[j][Z] - q[i][Z];
      const double r2 = (dx*dx + dy*dy + dz*dz);         const double r2 = (dx*dx + dy*dy + dz*dz);
      const double r6 = r2*r2*r2;                        if (r2 > CUTOFF) continue;
      double df = (24.0*r6-48.0)/(r6*r6*r2)*dt;          const double r6 = r2*r2*r2;
      p[i][X] += df*dx;                                  double df = (24.0*r6-48.0)/(r6*r6*r2)*dt;
      p[i][Y] += df*dy;                                  p[i][X] += df*dx;
      p[i][Z] += df*dz;                                  p[i][Y] += df*dy;
      p[j][X] -= df*dx;                                  p[i][Z] += df*dz;
      p[j][Y] -= df*dy;                                  p[j][X] -= df*dx;
      p[j][Z] -= df*dz;                                  p[j][Y] -= df*dy;
    }                                                    p[j][Z] -= df*dz;
  }                                                    }
}                                                    }
                                                   }

  条件分岐により、必要な計算量は80%程度に減る	
                                                                                          University of Tokyo
40/76	
              条件分岐コスト (2/2)	




                                    条件分岐なし	
経過時間[s]	
                                    条件分岐あり	




   条件分岐がなければIBM POWERの方がIntel Xeonより早いが
   条件分岐があると、大幅に遅くなる

     IBM POWER、SPARC (京やFX10)は、条件分岐に弱い




                                          University of Tokyo
41/76	
                           条件分岐削除 (1/2)

1.    foreach interacting particles	
2.    r ← particle distance	
3.    if distance > cutoff length then continue	
 ここが重い
4.    f ← calculate force	
                    (次のループが回るかわからないから)	
5.    p ← update momenta	
6.    next



1.    foreach interacting particles	
2.    r ← particle distance	
3.    f ← calculate force	
4.    if distance > cutoff length then f ←0    fsel 命令が使われる	
5.    p ← update momenta	
                    (全てのループが確実にまわる)	
6.    next
      余計な計算量が増えるが、パイプラインがスムーズに流れる
      ために計算が早くなる(こともある)
                                                            University of Tokyo
42/76	
                  条件分岐削除 (2/2)

                                               条件分岐なし	
                                               条件分岐あり	
                                               条件分岐削除	

経過時間[s]	




IBM POWERでの実行が大幅に高速化された
IBM POWERや、京には条件代入命令(fsel)がある	
   fsel	
 	
 fp0,fp1,fp2,fp3	
 
   fp0	
 =	
 (fp1	
 >	
 0)?	
 fp2:	
 fp3;	
 
 これにより、マスク処理が可能	
                                     University of Tokyo
43/76	
                SIMD化 (1/4)	
SIMD化とは何か	
 コンパイラが出力する命令のうち、SIMD命令の割合を増やす事	

 スカラ命令: 一度にひとつの演算をする
 SIMD命令(ベクトル命令):複数の対象にたいして、同種の演算を一度に行う	

実際にやること	
 コンパイラがSIMD命令を出しやすいようにループを変形する	
  SIMD命令が出しやすいループ:
   演算に依存関係がすくないループ	
  コンパイラがどうしてもSIMD命令を出せなかったら?	

      手作業によるSIMD化        ほとんどアセン
      (Hand-SIMDize)	
   ブリで書くよう
                          なものです	
                                    University of Tokyo
44/76	
                              SIMD化 (2/4)	
ループアンローリング	
DO	
 I	
 =	
 1,	
 N	
 
	
 	
 C[i]	
 =	
 A[i]	
 +	
 B[i]	
  依存関係があるのでSIMD命令が発行されない。
	
 	
 E[i]	
 =	
 C[i]	
 +	
 D[i]	
 
	
 	
 G[i]	
 =	
 E[i]	
 +	
 F[i]	
 
	
 	
 I[i]	
 =	
 G[i]	
 +	
 H[i]	
 
END	
 DO	
 
ループを二倍展開し、独立な計算を作る (馬鹿SIMD化)	
                                 コンパイラが
  A[1]+B[1]	
   A[2]+B[2]	
      Loop Unrolled x times
 C[1]+D[1]	
 C[2]+D[2]	
         とメッセージ出したらおそらくこれ

  E[1]+F[1]	
   E[2]+F[2]	
      問題点:
  I[1]+G[1]	
   I[2]+G[2]	
      ・レイテンシを隠しづらい
                                 ・積和が作りにくい
                                 → 遅い


                                                         University of Tokyo
45/76	
                          SIMD化 (3/4)	
ソフトウェアパイプライニング	
                               DO I = 1, N
ループインデックス	
                                     C[i] = A[i] + B[i]
                                                E[i] = C[i] + D[i]
     A[1]+B[1]	
                                H[i] = F[i] + G[i]
     C[1]+D[1]	
   A[2]+B[2]	
                  H[i] = H[i] + I[i]
                                               END DO	
     E[1]+F[1]	
   C[2]+D[2]	
   A[3]+B[3]	
     I[1]+G[1]	
   E[2]+F[2]	
   C[3]+D[3]	
   A[4]+B[4]	
                   I[2]+G[2]	
   E[3]+F[3]	
   C[4]+D[4]	
                                 I[3]+G[3]	
   E[4]+F[4]	
                                               I[4]+G[4]	
 独立な計算を増やしやすい
 レイテンシを隠し易い
 人間の手でやるのはかなり厳しい
 だが、FX10ではこれをやらないと速度が出ない
  →いかにコンパイラに「Loop software pipelined」を出させるか
                                                                     University of Tokyo
46/76	
                  SIMD化 (4/4)	
我々が実際にやったこと	
作用反作用を使わない (二倍計算する)
 → FX10ではメモリへの書き戻しがボトルネックだった

ループを2倍展開した馬鹿SIMDループをさらに二倍アンロール (4倍展開)
 → レイテンシ隠蔽のため、手でソフトウェアパイプライニング

局所一次元配列に座標データをコピー
 → 運動量の書き戻しは行わないので、局所座標の読み出しがネックに
 → 「グローバル、static配列でないとsoftware pipeliningできない」
    というコンパイラの仕様に対応するため(もうなおったかも)

除算のSIMD化
 → FX10には除算のSIMD命令がない(たぶん)
 → 逆数近似命令(低精度)+精度補正コードを手で書いた。

チューニング成果	
 力の計算の速度は2倍に、全体でも30%程度の速度向上
                                            University of Tokyo
47/76	
          CPUチューニングのまとめ
CPU依存のチューニングは、当然のことながらCPUに依存する
→ CPUを変えるたびにチューニングしなおし
→ プログラムの管理も面倒になる	


    そこまでやる必要あるんですか?	


         基本的には趣味の世界です。	



世の中には全部intrinsic 命令でホットスポットを書く廃人もいるにはいる	
                                       University of Tokyo
48/76	




並列化、その前に	




             University of Tokyo
49/76	
             並列化、その前に (1/3)
並列化とは何か?	

 複数のノードを使う事で、時間か空間を稼ぐ方法	
時間を稼ぐ並列化	
一つのコアあたりの計算量を減らすことで、計算規模をそのままに
計算時間を短くする (ストロングスケーリング)	

空間を稼ぐ並列化	

 ひとつのノードでは扱えないような大きな問題を扱いたい
 ひとつのコアあたりの計算量はそのままに、コア数を増やすことで
 サイズを大きくする(ウィークスケーリング)	




                              University of Tokyo
50/76	
               並列化、その前に (2/3)
通信時間	
 通信時間には、レイテンシとバンド幅が関係
 レイテンシ:通信がはじまるまでの時間
 バンド幅:単位時間あたりどれだけのデータを通信できるか	
並列化の粒度	
 計算時間と通信時間の比	
    計算	
  通信	

Granularity が疎 (計算ドミナント) 
大規模計算向き	
Granularity が密(通信ドミナント) 
大規模計算が難しい	

 ストロングスケーリング(計算規模をそのままにコア数を増やす)
 では、粒度が密になり、レイテンシが問題となる
                                University of Tokyo
51/76	
                並列化、その前に (3/3)
現象と計算コスト
     非平衡非定常系	
                           平衡系、非平衡定常系	


タイムスケールはサイズ依存性が弱い                      緩和にかかる時間が系のサイズに依存
(核生成、音速、爆発)                            (遅い緩和を持つ現象はさらに厳しい)


粒子数と扱える現象
                                          非平衡現象                   平衡状態
論文としてpublishされたもの	
    ベンチマーク           (単一気泡生成)            (気液相転移の臨界指数)
                      4.1G Particles     12M Particles 	
      1.6M Particles	
                                          非平衡現象
    今回紹介する計算	
          ベンチマーク           (多重核生成)
                       38G Particles    1.4G Particles 	

同じ計算資源を使った場合、定常状態は非定常状態に比べてサイズが桁で落ちる
大規模計算では非平衡非定常系の計算が向いている	

       ベンチマーク > 1     3桁 > 非平衡 > 1             2桁 > 平衡状態 	
                                                                         University of Tokyo
52/76	




並列化の方法	




           University of Tokyo
53/76	
 並列化の方法 (1/2)	




並列化をがんばる




                  University of Tokyo
54/76	
             並列化の方法 (2/2)	

 ・・・これだけではあんまりなので、注意点(心構え)を二点だけ	

「並列化」の限界	
 既存のソースコードを「並列化」して得られる性能には限りがある
 本当に大規模計算を志すなら、最初から「並列コード」を書くべき
 最終的には何度も書き直すことになる	

ベンチマークからが勝負	
計算科学においては、「科学論文を書くこと」が一応のゴール
大規模なベンチマークに成功しても、それだけでは論文が書けない
特に、観測ルーチンの並列化や、計算条件の調査に時間がかかる	


       あとは並列化のノウハウを少し紹介	
                              University of Tokyo
55/76	
               Flat MPIか、ハイブリッドか	
コア・CPU・ノード	
 複数のコアの集合→CPU                ノード内はメモリ共有
 複数のCPUの集合→ノード
                             ノード間はメモリ分散	
 複数のノードの集合→スパコン	
OpenMPとMPI	
 OpenMP 共有メモリ型並列スキーム (ノード内) ← スレッド
 MPI    分散メモリ型並列スキーム (ノード間) ← プロセス	

一般に、Flat-MPIの方が早いが、メモリ消費も大きい
   物性研 1024コア、コアあたり50万粒子
   Flat-MPI: 1024 プロセス   276.5GB
   Hybrid: 128プロセス*8スレッド 199.1GB	

全く同じ計算をしても、Flat-MPIではノードあたり
600MB程度利用メモリが増加する

→ 大規模計算ではMPI+OpenMPのハイブリッド並列必須	
                                            University of Tokyo
56/76	
              ハイブリッド並列化(1/6)	
スレッドとプロセス	
                  タスク	
        プロセス	
    プロセス	
    プロセス	
                  メモリ空間	
   メモリ空間	
        メモリ空間	
                  スレッド	
    スレッド	
        スレッド	
    スレッド	
    スレッド	


 プロセス:OSから見た利用単位
       ひとつ以上のスレッドと、プロセスごとに固有メモリ空間を持つ。
 スレッド: CPUから見た利用単位。同じプロセス中のスレッドはメモリを共有する
 タスク: 人間から見た利用単位。
      一つ以上のプロセスが協調して一つの仕事を実行する単位。	




                                      University of Tokyo
57/76	
                 ハイブリッド並列化(2/6)	
スレッド並列	
 プロセス内で並列処理 ( ノード内並列)          プロセス	
 メモリ共有型
 →排他制御が必要                     メモリ空間	
 OpenMP、コンパイラの自動並列
                            スレッド	
    スレッド	
 始めるのは簡単、性能を出すのは困難	
                            スレッド	
    スレッド	
プロセス並列	
 プロセス間で並列処理 ( ノード間並列)                タスク	
 メモリ分散型                    プロセス	
            プロセス	
 →明示的通信が必要
 MPIライブラリ                  メモリ空間	
           メモリ空間	

 敷居は高いが、性能予測はし易い	
                   通信	
                           スレッド	
            スレッド	
ハイブリッド並列	
                           スレッド	
            スレッド	
プロセス並列とスレッド並列を両方やること	
           面倒くさい	
                                               University of Tokyo
58/76	
                  ハイブリッド並列化(3/6)	
一般的方法	
 MPI: 空間分割
 OpenMP: ループ分割	

   DO I=1,N           ここか、
    DO J in Pair(I)   ここにスレッド並列をかける	
     CalcForce(I,J)
    ENDDO
   ENDDO

問題点	
 運動量の書き戻しで同じ粒子にアクセスする可能性がある
 → テンポラリバッファを用意して衝突をさける
 → 作用反作用を使わない
 ペアリスト作成もスレッド並列化しなければならない
 力の計算というボトルネックで、SIMD化とOpenMP化を同時に扱う必要がある	


                                        University of Tokyo
59/76	
                             ハイブリッド並列化(4/6)	
 完全空間分割	
                                              プロセス	
           スレッド	
    MPI: 空間分割
    OpenMP: 空間分割	
                                MDUnit	
 MDUnit	
 MDUnit	
 MDUnit	
     MDUnitクラス:
      分割された領域を担当するクラス
     MDManagerクラス                                 MDUnit	
 MDUnit	
 MDUnit	
 MDUnit	
      MDUnitを束ねて、通信をするクラス	


   DO I=1,THREAD_NUM                     ここにスレッド並列をかける	
    CALL MDUnit[i]->Calculate()
   ENDDO
                                    MDManager	
                        MDManager	
MPIプロセス = MDManager
MDManagerがMDUnitを1つ担当 = Flat MPI
                                                          通信	
MDManagerがMDUnitを複数担当=Hybrid
                                   MDUnit	
 MDUnit	
                  MDUnit	
 MDUnit	



                                   MDUnit	
 MDUnit	
                  MDUnit	
 MDUnit	


                                                                               University of Tokyo
60/76	
                     ハイブリッド並列化(5/6)	
スレッドからのMPI通信	
スレッドはプロセスより「軽い」かわりに、できることも限られる
例えば一般にスレッドからのMPI通信は許されて(実装されて)いない
以下の4種類の実装レベルが規定されている

  MPI_THREAD_SINGLE	
        MPI_THREAD_FUNNELD	
     スレッドの通信不可	
               メインスレッドからなら通信可	
  プロセス	
          プロセス	
     プロセス	
       プロセス	

  メモリ空間	
         メモリ空間	
    メモリ空間	
     メモリ空間	

  スレッド	
          スレッド	
     スレッド	
       スレッド	

  スレッド	
          スレッド	
     スレッド	
       スレッド	


 MPI_THREAD_SERIALIZED	
     MPI_THREAD_MULTIPLE	
同時に一つまでなら通信可能 (京、物性研)	
      どのスレッドからでも自由に通信可	
  プロセス	
          プロセス	
      プロセス	
       プロセス	
  メモリ空間	
         メモリ空間	
     メモリ空間	
     メモリ空間	
  スレッド	
    1	
   スレッド	
       スレッド	
      スレッド	
  スレッド	
    2	
   スレッド	
       スレッド	
      スレッド	
                                                     University of Tokyo
61/76	
            ハイブリッド並列化(6/6)	
完全空間分割のメリット	
 MDUnitクラスは、自分がスレッドであるかプロセスであるかを意識しなくてよい
 二種類のロードバランスを考えなくてよい
 → Flat-MPIがスケールする領域であれば、ハイブリッドでもスケールする

 NUMA最適化を考えなくてよい(京、FX10では関係ない)

 力の計算は、SIMD化のみ考えれば良い


完全空間分割のデメリット	
 通信が面倒くさい
 →処理系によっては、スレッドからのMPI通信が実装されていない
 →マスタースレッドにまとめて通信する必要がある

 観測ルーチンを組むのが面倒くさい
 →通信がすべて二段になっているため
                                    University of Tokyo
62/76	
               MPIを使う際の注意点
 小さいジョブが成功したのに大きなジョブが失敗・・・なぜ?	
               MPIはリソースをかなり消費するから	
ノンブロッキング通信	

 直接通信	
              Process1	
     Process2	


                                  Buffer
                                  (heap)	
 バッファ通信	
           Process1	
                   Process2	

 ノンブロッキング通信はバッファを多く使うため、大きいジョブでメモリ不足に陥り易い
 (実はブロッキング通信を指定しても、ノンブロッキング通信が呼ばれる可能性がある)	

 典型的には「MPI_なんとか_MAX」が足りない、というエラーメッセージが良く出る。
 対応する環境変数などを調べること。
 対応策としては、通信を小分けにする、こまめにバッファをクリアするなど・・・

MPIの実装はベンダーに強く依存する。
あるシステムで問題なく動作したプログラムが他のところで動かない、ということはよくある

                                                  University of Tokyo
63/76	
             馬鹿パラの是非
馬鹿パラとは
 乱数の種やパラメータを変えたジョブを多数投入すること
 自明並列(trivial parallelization)とも。
 通信が発生しないため、見た目の並列化効率は100%

やってはいけない馬鹿パラ
 乱数の種を変えて、物理量の統計平均を稼ぐ馬鹿パラ	
  統計精度は、サンプル数の平方根に比例する
  したがって、100倍の計算資源をつぎ込んでも、
  得られる精度向上は10倍程度→実質並列化効率10%
    莫大なサンプル数による統計平均が必要なジョブを
    超並列計算機で行う、というのは筋が悪い
※ パラメータ並列も拡張アンサンブルやGAを使うなど工夫したほうが良いと思う	
                                      University of Tokyo
64/76	




大規模計算では何ができるか	

    渡辺の研究紹介	




                University of Tokyo
65/76	
             気液混相流の全粒子計算	
気液混相流	
                          階層的モデリング	
マクロな輸送現象(熱、粒子、運動量)と	
    相転移	
     気泡間相互作用	
    流動現象	

ミクロな相転移のカップルした非平衡状態	

数値計算課題として	
マルチスケール、マルチフィジックス	
境界の移動、生成、消滅

階層的モデリング	
 スケールにより現象を分類	
 それぞれに支配方程式を仮定する	
                                   粒子間相互作用	
 ・人為的な階層定義	
 ・支配方程式の妥当性の検証	

   分子動力学法による全粒子計算
   →大規模計算	
               Movie	
            全粒子計算	
                                               University of Tokyo
66/76	
                  ベンチマーク (1/3)
計算の詳細	
カットオフ 2.5、密度 0.5、初期条件: FCC、時間刻み: 0.001
積分法:二次のシンプレクティック
150ステップ後、1000ステップの計算にかかった時間を計測

東京大学情報基盤センター Oakleaf (FX10) 4800ノードを使って計測
(1.13ペタフロップス)
並列化	
 Flat MPI :16プロセス/node 最大 76800プロセス
 Hybrid: 16 スレッド/node  最大 4800プロセス、76800スレッド 	




                                                  University of Tokyo
67/76	
            ベンチマーク (2/3)




ウィークスケーリング
(ノードあたりの計算量を固定したままノード数を増加)
Flat MPIのスケーリングはほぼ完璧
Hybridの速度は不安定、かつFlat MPIの二倍程度遅い
                                  University of Tokyo
68/76	
                       ベンチマーク (3/3)


                                        4800 node
                                      38.4G Particles
                                      105229 MUPS

                                       (384億粒子)	




  1 node
8M Particles
22.7 MUPS




MUPS: Million Updates Per Seconds	
   ウィークスケーリング
   (ノードあたりの計算量を固定したままノード数を増加)
   最大で4800ノード、76800プロセス、384億粒子
   そろそろMUPSじゃなくてGUPSの領域	
              University of Tokyo
69/76	
                   急減圧シミュレーション	
計算の詳細	
                                                    G	
                   Liquid	




                                    Temperature	
初期密度と温度: T=0.9, ρ=0.7 (純液相)
減圧強さ:一辺 1.025倍 (密度 0.7→0.65: 強減圧)
時間刻み:0.005
カットオフ:3.0                                                 Coexistence	
周期境界条件	
数値積分法:二次のシンプレクティック(NVE)
     	
 二次のRESPA (NVT)
緩和: 1万ステップ	
トータルステップ数:
 70万ステップ(ISSP)
 18万ステップ(FX10)	
                                                             Density	

計算の規模	
 物性研:                      情報基盤センター:
 1024プロセス                  4800プロセス (76800スレッド)
 320*320*320               1440*1200*1200     物性研の64倍	
 22937600粒子                1449776020粒子
 70万ステップに10時間	
            18万ステップに15時間	
     Hybrid実行	

  Flat-MPI実行	
      Movie	
                                                                            University of Tokyo
70/76	
           多重核生成からOstwald成長へ	
物性研の計算結果 (2300万粒子)

 初期ステージ	
        中間ステージ	
         最終ステージ	




 多重核生成	
    気泡間相互作用による「つぶしあい」	
   単一気泡へ収束	
FX10の計算結果 (14億5千万粒子)




多重核生成から気泡間相互作用フェーズへ	
                                      University of Tokyo
71/76	
        気泡の分布関数 (1/2)	


                          FX10 (L=1440)	

                          ISSP (L=320)	




減圧後、一万ステップ後の気泡分布関数 (体積で規格化)
→ 気泡サイズの大きい領域で統計が取れていない

                                    University of Tokyo
72/76	
             気泡の分布関数 (2/2)	

   ISSP (L=320)	
        FX10 (L=1440)	




減圧後、一万ステップ後の気泡分布スナップショット

      初期ステージにおいても、気泡分布関数をきれいに
      見るためには最低でも一億粒子は必要	
                                      University of Tokyo
73/76	
                       ロードバランス	
粒子系でのロードバランス	
領域分割法における計算コストは、担当領域の粒子密度に比例
       初期密度:0.7 → 減圧後: 0.65	
→完璧なロードバランスが達成されたら、計算コストは0.65に比例	

減圧後、気相と液相に分離	
                                  計算コスト	
 初期温度:0.9 → 減圧後: 0.88
 この温度における共存密度
 気相密度: 0.0344                実際のコスト	

 液相密度: 0.687                 理想的な場合	

毎ステップバリア同期を取っているため
計算速度は一番遅い領域が決める
一番遅い領域は、純液相領域 (密度0.687)	
                                        プロセス1	
 プロセス2	
 プロセス3	
 プロセス4	
 プロセス5	

       ロードバランスの悪化
       0.65 / 0.687 0.95	

      急減圧シミュレーションにおいては、ロードインバランスは問題にならない	
                                                                   University of Tokyo
74/76	
                 現象とスケール	
                            We are here	
物理現象	

Micro                                  Macro




    気泡生成
                                   気泡流
                 多重気泡生成
                                   (相転移と流動のカップリング)

必要粒子数	



Linear Scale	
    10 nm	
      100 nm	
               1 um	
                                                 University of Tokyo
75/76	
            大規模計算でなにができたか	
ベンチマーク	
 最大4800ノード、76800プロセスで384億粒子の計算を実行
 FX10向けのチューニングにより、ピーク性能比 17% (193TFLOPS)	
 FlatMPIに比べてハイブリッド並列は遅く、かつ性能が安定しない
 しかし、ハイブリッド並列の方がメモリ消費は小さい

                              1ノードあたりのメモリ消費
                              Hybrid: 10GB/28GB
急減圧による多重気泡生成過程	
              FlatMPI: 14GB/28GB

 14億粒子による急減圧シミュレーション
 大規模ハイブリッドコードが15時間完走
 76800コア×15時間 = 131コア年
 → これだけ長時間破綻せずに走るためには事前の綿密なデバッグが不可欠	

 粒子間相互作用により気泡生成
 気泡間相互作用によりOstwald的成長	
           マルチスケールな現象の直接計算に成功	
                                             University of Tokyo
76/76	
        全体のまとめ	


高速化、並列化は好きな人がやればよい

なぜなら科学とは好きなことをするものだから	




                    University of Tokyo

Weitere ähnliche Inhalte

Was ist angesagt?

遠赤外線カメラと可視カメラを利用した悪条件下における画像取得
遠赤外線カメラと可視カメラを利用した悪条件下における画像取得遠赤外線カメラと可視カメラを利用した悪条件下における画像取得
遠赤外線カメラと可視カメラを利用した悪条件下における画像取得
Masayuki Tanaka
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
智啓 出川
 
ノンパラメトリックベイズを用いた逆強化学習
ノンパラメトリックベイズを用いた逆強化学習ノンパラメトリックベイズを用いた逆強化学習
ノンパラメトリックベイズを用いた逆強化学習
Shota Ishikawa
 

Was ist angesagt? (20)

マルコフ連鎖モンテカルロ法入門-1
マルコフ連鎖モンテカルロ法入門-1マルコフ連鎖モンテカルロ法入門-1
マルコフ連鎖モンテカルロ法入門-1
 
海鳥の経路予測のための逆強化学習
海鳥の経路予測のための逆強化学習海鳥の経路予測のための逆強化学習
海鳥の経路予測のための逆強化学習
 
あなたの心にBridgeSampling
あなたの心にBridgeSamplingあなたの心にBridgeSampling
あなたの心にBridgeSampling
 
[DL輪読会]Control as Inferenceと発展
[DL輪読会]Control as Inferenceと発展[DL輪読会]Control as Inferenceと発展
[DL輪読会]Control as Inferenceと発展
 
サポートベクターマシン(SVM)の数学をみんなに説明したいだけの会
サポートベクターマシン(SVM)の数学をみんなに説明したいだけの会サポートベクターマシン(SVM)の数学をみんなに説明したいだけの会
サポートベクターマシン(SVM)の数学をみんなに説明したいだけの会
 
Deep Learning Lab 異常検知入門
Deep Learning Lab 異常検知入門Deep Learning Lab 異常検知入門
Deep Learning Lab 異常検知入門
 
畳み込みLstm
畳み込みLstm畳み込みLstm
畳み込みLstm
 
人工知能2018 5 機械学習の基礎
人工知能2018 5 機械学習の基礎人工知能2018 5 機械学習の基礎
人工知能2018 5 機械学習の基礎
 
Ponanzaにおける強化学習とディープラーニングの応用
Ponanzaにおける強化学習とディープラーニングの応用Ponanzaにおける強化学習とディープラーニングの応用
Ponanzaにおける強化学習とディープラーニングの応用
 
確率的主成分分析
確率的主成分分析確率的主成分分析
確率的主成分分析
 
遠赤外線カメラと可視カメラを利用した悪条件下における画像取得
遠赤外線カメラと可視カメラを利用した悪条件下における画像取得遠赤外線カメラと可視カメラを利用した悪条件下における画像取得
遠赤外線カメラと可視カメラを利用した悪条件下における画像取得
 
[DL輪読会]Grandmaster level in StarCraft II using multi-agent reinforcement lear...
[DL輪読会]Grandmaster level in StarCraft II using multi-agent reinforcement lear...[DL輪読会]Grandmaster level in StarCraft II using multi-agent reinforcement lear...
[DL輪読会]Grandmaster level in StarCraft II using multi-agent reinforcement lear...
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
 
大阪PRML読書会#1資料
大阪PRML読書会#1資料大阪PRML読書会#1資料
大阪PRML読書会#1資料
 
PCAの最終形態GPLVMの解説
PCAの最終形態GPLVMの解説PCAの最終形態GPLVMの解説
PCAの最終形態GPLVMの解説
 
分割時系列解析(ITS)の入門
分割時系列解析(ITS)の入門分割時系列解析(ITS)の入門
分割時系列解析(ITS)の入門
 
第4回 配信講義 計算科学技術特論B(2022)
第4回 配信講義 計算科学技術特論B(2022)第4回 配信講義 計算科学技術特論B(2022)
第4回 配信講義 計算科学技術特論B(2022)
 
ノンパラメトリックベイズを用いた逆強化学習
ノンパラメトリックベイズを用いた逆強化学習ノンパラメトリックベイズを用いた逆強化学習
ノンパラメトリックベイズを用いた逆強化学習
 
畳み込みネットワークによる高次元信号復元と異分野融合への展開
畳み込みネットワークによる高次元信号復元と異分野融合への展開 畳み込みネットワークによる高次元信号復元と異分野融合への展開
畳み込みネットワークによる高次元信号復元と異分野融合への展開
 
[DL輪読会]近年のエネルギーベースモデルの進展
[DL輪読会]近年のエネルギーベースモデルの進展[DL輪読会]近年のエネルギーベースモデルの進展
[DL輪読会]近年のエネルギーベースモデルの進展
 

Ähnlich wie 短距離古典分子動力学計算の 高速化と大規模並列化

Principles of Transaction Processing Second Edition 9章 4~9節
Principles of Transaction Processing Second Edition 9章 4~9節Principles of Transaction Processing Second Edition 9章 4~9節
Principles of Transaction Processing Second Edition 9章 4~9節
Yuichiro Saito
 
VLDB'10勉強会 -Session 2-
VLDB'10勉強会 -Session 2-VLDB'10勉強会 -Session 2-
VLDB'10勉強会 -Session 2-
Takeshi Yamamuro
 
SIGMOD'10勉強会 -Session 8-
SIGMOD'10勉強会 -Session 8-SIGMOD'10勉強会 -Session 8-
SIGMOD'10勉強会 -Session 8-
Takeshi Yamamuro
 
2012-04-25 ASPLOS2012出張報告(公開版)
2012-04-25 ASPLOS2012出張報告(公開版)2012-04-25 ASPLOS2012出張報告(公開版)
2012-04-25 ASPLOS2012出張報告(公開版)
Takahiro Shinagawa
 

Ähnlich wie 短距離古典分子動力学計算の 高速化と大規模並列化 (20)

Tuning, etc.
Tuning, etc.Tuning, etc.
Tuning, etc.
 
El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613
 
kagami_comput2016_14
kagami_comput2016_14kagami_comput2016_14
kagami_comput2016_14
 
Principles of Transaction Processing Second Edition 9章 4~9節
Principles of Transaction Processing Second Edition 9章 4~9節Principles of Transaction Processing Second Edition 9章 4~9節
Principles of Transaction Processing Second Edition 9章 4~9節
 
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術2
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術2CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術2
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術2
 
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術1
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術1CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術1
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術1
 
VLDB'10勉強会 -Session 2-
VLDB'10勉強会 -Session 2-VLDB'10勉強会 -Session 2-
VLDB'10勉強会 -Session 2-
 
kagamicomput201814
kagamicomput201814kagamicomput201814
kagamicomput201814
 
SpectreとMeltdown:最近のCPUの深い話
SpectreとMeltdown:最近のCPUの深い話SpectreとMeltdown:最近のCPUの深い話
SpectreとMeltdown:最近のCPUの深い話
 
Development and Experiment of Deep Learning with Caffe and maf
Development and Experiment of Deep Learning with Caffe and mafDevelopment and Experiment of Deep Learning with Caffe and maf
Development and Experiment of Deep Learning with Caffe and maf
 
アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニング
 
シンプルでシステマチックな Linux 性能分析方法
シンプルでシステマチックな Linux 性能分析方法シンプルでシステマチックな Linux 性能分析方法
シンプルでシステマチックな Linux 性能分析方法
 
本当にわかる Spectre と Meltdown
本当にわかる Spectre と Meltdown本当にわかる Spectre と Meltdown
本当にわかる Spectre と Meltdown
 
並行実行制御の最適化手法
並行実行制御の最適化手法並行実行制御の最適化手法
並行実行制御の最適化手法
 
KOGEI & KAIT Funnel WS
KOGEI & KAIT Funnel WSKOGEI & KAIT Funnel WS
KOGEI & KAIT Funnel WS
 
SIGMOD'10勉強会 -Session 8-
SIGMOD'10勉強会 -Session 8-SIGMOD'10勉強会 -Session 8-
SIGMOD'10勉強会 -Session 8-
 
kagamicomput201714
kagamicomput201714kagamicomput201714
kagamicomput201714
 
CMSI計算科学技術特論A (2015) 第9回
CMSI計算科学技術特論A (2015) 第9回CMSI計算科学技術特論A (2015) 第9回
CMSI計算科学技術特論A (2015) 第9回
 
【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門 【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門
 
2012-04-25 ASPLOS2012出張報告(公開版)
2012-04-25 ASPLOS2012出張報告(公開版)2012-04-25 ASPLOS2012出張報告(公開版)
2012-04-25 ASPLOS2012出張報告(公開版)
 

Mehr von Hiroshi Watanabe

Mehr von Hiroshi Watanabe (8)

Enjoy supercomputing
Enjoy supercomputingEnjoy supercomputing
Enjoy supercomputing
 
AVX命令を用いたLJの力計算のSIMD化
AVX命令を用いたLJの力計算のSIMD化AVX命令を用いたLJの力計算のSIMD化
AVX命令を用いたLJの力計算のSIMD化
 
MDとはなにか
MDとはなにかMDとはなにか
MDとはなにか
 
Huge-Scale Molecular Dynamics Simulation of Multi-bubble Nuclei
Huge-Scale Molecular Dynamics Simulation of Multi-bubble NucleiHuge-Scale Molecular Dynamics Simulation of Multi-bubble Nuclei
Huge-Scale Molecular Dynamics Simulation of Multi-bubble Nuclei
 
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの 〜並列編〜
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの 〜並列編〜短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの 〜並列編〜
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの 〜並列編〜
 
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
短距離ハイブリッド並列分子動力学コードの設計思想と説明のようなもの
 
130613-debug
130613-debug130613-debug
130613-debug
 
ハイパースレッディングの並列化への影響
ハイパースレッディングの並列化への影響ハイパースレッディングの並列化への影響
ハイパースレッディングの並列化への影響
 

短距離古典分子動力学計算の 高速化と大規模並列化

  • 1. 1/76 短距離古典分子動力学計算の 高速化と大規模並列化 渡辺宙志 東京大学物性研究所 Outline 1.  チューニング、その前に 2.  計算機の仕組みと高速化 3.  並列化 4.  大規模計算でなにができるか 5.  まとめ Dec. 13, 2012「第6回分子シミュレーションスクール」@岡崎カンファレンスホール University of Tokyo
  • 3. 3/76 チューニング、その前に (1/5) A fast runner is not a good soccer player. H. Watanabe, 2012 University of Tokyo
  • 4. 4/76 チューニング、その前に (2/5) 最適化の第一法則:最適化するな 最適化の第二法則(上級者限定):まだするな Michael A. Jackson, 1975 University of Tokyo
  • 5. 5/76 チューニング、その前に (3/5) なぜ最適化するのか? プログラムの実行時間を短くするため なぜ実行時間を短くしたいのか? 計算結果を早く手に入れるため なぜ計算結果を早く手にいれたいのか? 論文を早く書くため ← ここがとりあえずのゴール 最適化、並列化をする際には、必ず「いつまでに論文執筆まで 持って行くか」を意識すること。だらだらと最適化にこだわらない。 University of Tokyo
  • 6. 6/76 チューニング、その前に (4/5) Q. 最適化、並列化でもっとも大事なことは何か? A. バグを入れないこと 通常、プログラミングにおいて最も時間のかかるプロセスは デバッグだから University of Tokyo
  • 7. 7/76 チューニング、その前に (5/5) バグを入れない方法 いろいろあるが、特に以下の二つの方法が有効 ・単体テスト ・sort + diff デバッグ 単体テスト ・テストしようとしている部分だけを切り出す ・その部分だけでコンパイル、動作するような最低限のインターフェース ・最適化、並列化する前と後で結果が一致するかを確認する ・本番環境でテストしない sort + diff デバッグ ・print文デバッグの一種 ・出力情報を保存し、sortしてからdiffを取る ・単体テストと組み合わせて使う University of Tokyo
  • 8. 8/76 sort + diff デバッグの例1 - 粒子対リスト作成 (1/3) ペアリストとは? ・相互作用距離(カットオフの距離)以内にある粒子対のリスト ・どの粒子同士が近いか?という情報 ・全粒子対についてチェックすると    ・高速に粒子対を作成する方法 → グリッド探索 グリッド法 ・空間をグリッドに切り、その範囲に存在する粒子を登録する 排他的グリッド(Exclusive Grid )法 非排他的グリッド(Non-Exclusive Grid )法 一つのグリッドに粒子一つ 一つのグリッドに複数粒子 ・短距離相互作用 ・長距離相互作用 ・二次元 ・三次元 ・高密度 ・低密度 University of Tokyo
  • 9. 9/76 sort + diff デバッグの例1 - 粒子対リスト作成 (2/3) ポイント O(N^2)法は、計算時間はかかるが信頼できる O(N)法とO(N^2)法は、同じconfigurationを与えられたら、 同じペアリストを作るはず 手順 初期条件を作るルーチンを作る ペアリスト作成ルーチンを作り、コンパイル、実行できるようにする (単体テスト) O(N)とO(N^2)ルーチンに初期条件を与え、作成したペアリストをダンプする ダンプ方法:作成された粒子対の、番号が若い方を左にして、一行に1ペア O(N)とO(N^2)でリストの順番が異なるはずなのでsortする $ ./on2code | sort > o2.dat $ ./on1code | sort > o1.dat diffを取る $ diff o1.dat o2.dat 結果が正しければdiffは何も出力しない いきなり本番環境に組み込んで時間発展、などとは絶対にしない University of Tokyo
  • 10. 10/76 sort + diff デバッグの例1 - 粒子対リスト作成 (3/3) 並列版のデバッグ ペアリスト作成の並列化 ・はじっこの粒子が正しく渡されているか? ・周期境界条件は大丈夫か? 手順 初期条件を作るルーチンを作る 並列版と非並列版のペアリスト作成ルーチンを作る 非並列版はそのままペアリストをダンプ 並列版は「若い番号の粒子が自分の担当の粒子」 であるときだけダンプ sort + diffで一致を確認する ポイント まず、並列版と非並列版両方O(N^2)で試す →粒子の受け渡しがバグっているのか、O(N)の並列化が間違っているのか 区別するため 一度に複数の項目を同時にテストしない University of Tokyo
  • 11. 11/76 sort + diff デバッグの例2 - 粒子情報送信 端の粒子の送り方 ナイーブな送り方 正しく情報が送られているかをチェックする →粒子の情報を送る前と、送ったあとそれぞれで 全粒子座標を出力してsort+diff 通信方法を減らした送り方 (もらった粒子をさらに転送することで斜め通信をなくす) University of Tokyo
  • 12. 12/76 チューニングをする前に ・新しい機能を追加するたびに単体テストをする ・高速化をためしたら、かならず単体テストをする 単体テストとは、ミクロな情報がすべて一致するのを確認することであ り、エネルギー保存など、マクロ量のチェックは単体テストではない ・時間はかかるが信用できる方法と比較する  「確実にここまでは大丈夫」という「砦」を築いて行く作業 ・複数の機能を一度にテストしない ・特に並列プログラムはバグを入れるととても大変なので、事前に  十分なデバッグが必要 デバッグとは、入れたバグを取ることではなく、そもそもバ グを入れないことである University of Tokyo
  • 13. 13/76 計算機の仕組み University of Tokyo
  • 14. 14/76 計算機の仕組みと高速化 高速化とは何か? ここでは「アルゴリズムを変えずに、実装方法によって 実行時間を短くする方法」と定義 → アルゴリズムレベルの最適化は終了していることを想定 遅いアルゴリズムを実装で高速化しても意味がないので、 十分にアルゴリズムレベルで最適化が済んでいることを確認すること 実装レベルの高速化とは何か? 「コンパイラや計算機にやさしいコードを書く事」 ※やさしい=理解しやすい、向いている そのためには、計算機の仕組みを理解しておかなければならない University of Tokyo
  • 15. 15/76 プログラム階層 ノード間通信 (並列化) Network メモリ転送 (キャッシュ最適化) Memory Memory Memory CPUコア (チューニング) Cache Cache Cache SIMD化、if分岐削除 CPU CPU CPU この中で最も重要なのはメモリ転送 University of Tokyo
  • 16. 16/76 記憶階層 Register FPU Register Register L1 L2 Memory FPU Register Floating Processing Unit CPU ・計算はレジスタ上で行う ・レジスタにのせられた情報はFPUに渡され、レジスタにかえってくる ・メモリアクセスで大事なのは、バンド幅とレイテンシ Latency CPUにデータを要求されてから、レジスタに届くまでのサイクル数 ・L1キャッシュで数サイクル、L2で10 20サイクル、主記憶は 数百サイクル Bandwidth CPUにデータが届き始めてからのデータ転送速度 絶対値(GB/s)よりも、計算速度との比(B/F)の方が良く使われる University of Tokyo
  • 17. 17/76 Byte / Flop Byte/Flop データ転送速度(Byte/s) と計算速度 (FLOPS)の比。略してB/F。 値が大きいほど、計算速度に比べたデータ転送能力が高い。 典型的には B/F = 0.1∼0.5 B/Fの意味 一つの倍精度実数(64bit)の大きさ = 8 Byte 計算するには、最低二つの倍精度実数が必要 = 16 Byte 最低でも一つの倍精度実数を書き戻す必要がある = 8 Byte. 例えば一回掛け算をして、その結果をメモリに書き戻すと、24Byteの読み書きが発生 B/F = 0.5 のマシンでは、24バイトの読み書きの間に48回計算ができる B/Fが0.5の計算機では、C = A*Bという単純な計算をくりかえすと ピーク性能の2%ほどしか出せず、ほとんど時間CPUが遊ぶ キャッシュ効率が性能に直結する University of Tokyo
  • 18. 18/76 仮想メモリとページング (1/2) Virtual Memory 現在の一般的なOSでは、メモリをページと呼ばれる仮想記憶で管理する。 ハードディスク 仮想メモリ 物理メモリ (論理メモリ) 連続配列が、物理メモリ内 では不連続に割り当てら れてるかもしれない 一部がハードディスクにスワップさ れているかもしれない 仮想メモリを使う理由 ・不連続なメモリ空間を論理的には連続に見せることができる  仮想メモリなしでは、メモリに余裕があっても連続領域が取れない場合にメモリ割り当てができない ・スワッピングが可能になる  記憶容量としてハードディスクも使えるため、物理メモリより広い論理 メモリ空間が取れる。 論理メモリと実メモリの対応が書いてあるのがTLB (テキスト参照) University of Tokyo
  • 19. 19/76 仮想メモリとページング (2/2) 数値計算で何が問題になるか? F90のallocateや、Cでnew、mallocされた時点では物理メモリの 割り当てがされていない場合がある real*8, allocatable :: work(:) allocate (work(10000)) この時点では予約だけされて、まだ物理アドレスが割り当てられない do i=1, 10000 work(i) = i はじめて触った時点で、アドレスがページ単位で割り当てられる end do (First touch の原則) よくある問題: 最初に馬鹿でかい配列を動的に確保しているプログラムの初期化がすごく遅い  地球シミュレータからT2Kへの移植で問題になることが多い。OSがLinuxである  京でも発生する 解決策:  メモリを静的に確保する(?)  mallocではなくcallocを使う (Fortranではどうやるのか知りません)  メモリを確保した直後、ページ単位で全体を触っておく まぁ、そういうこともあると覚えておいてください University of Tokyo
  • 20. 20/76 NUMA (1/2) NUMAとは 非対称メモリアクセス(Non-Uniform Memory Access)の略 CPUにつながっている物理メモリに近いメモリと遠いメモリの区別がある 京コンピュータはNUMAではないが、物性研System BはNUMA Fast access Memory Memory Memory CPU QPI CPU Memory Memory Memory Slow access 特にlatency University of Tokyo
  • 21. 21/76 NUMA (2/2) 数値計算で何が問題になるか? OpenMPでCPUをまたぐ並列化をする際、初期化を適当にやると 作業領域がコアから遠い物理メモリに割り当てられてしまう Touch CORE CORE CORE CORE QPI CORE CORE CORE CORE OpenMPのスレッドを作る前に配列を初期化  →root プロセスの近くにメモリ割り当て その後OpenMPでスレッド並列  →遠いメモリをアクセス(遅い) 解決策:  スレッドに対応する物理コアに近いところにメモリが割り当てられるように、スレッドごと に配列を用意した上、OpenMPでスレッド並列化した後にtouchとか 詳しくはNUMA最適化でググれ University of Tokyo
  • 22. 22/76 CPU (1/2) RISCと CISC 世の中のCPUアーキテクチャは大別して RISC型とCISC型の二種類 CISC:  ・比較的複雑な命令セット  ・if分岐などに強い (Out of order 実行)  ・Intel Xeon, AMD Opteronなど。 RISC:  ・比較的単純な命令セット  ・行列演算などに強い  ・IBM Power, SPARCなど (「京」はSPARC VIIIfx) RISCでOoOだったりするので、現在はあまり意味のある区別ではない。 要するに「Intel系か、それ以外か」という区別 マルチコアとSIMD化 最近のCPUはほぼマルチコア化とSIMD化で性能をかせいでいる ・マルチコアで性能を出すには、キャッシュとメモリの構造を把握する必要あり ・京(8コア) FX10 (16コア) IBM POWER6 (32コア)、SGI Altix ICE(4コア*2) ・SIMDについては後述 University of Tokyo
  • 23. 23/76 CPU (2/2) ゲーム機とCPU 第六世代 DC SH-4 PS2 MIPS (Emotion Engine), VLIW GC IBM PowerPC カスタム (Gekko) Xbox Intel Celeron (PenIII ベース) 第七世代 Wii IBM PowerPC カスタム Xbox 360 IBM PowerPC カスタム PS3 IBM Cell 3.2 University of Tokyo
  • 24. 24/76 レイテンシとパイプライン (1/3) レイテンシとは 命令が発行されてから、値が帰ってくるまでのクロック数 fadd fp2,fp0,fp1 # fp2 ← fp0 + fp1 fadd fp4,fp2,fp3 # fp4 ← fp2 + fp3 パイプライン fadd fp2,fp0,fp1 計算開始 計算中 計算中 計算中 計算中 計算中 計算終了 (fp2使用可) fadd fp4,fp2,fp3 University of Tokyo
  • 25. 25/76 レイテンシとパイプライン (2/3) パイプラインとは 浮動小数点の加算、減算、掛け算といった計算を流れ作業で行う仕組み fadd fp2,fp0,fp1 (A) fadd fp5,fp3,fp4 (B) fadd fp8,fp3,fp7 (C) (A) 1 (A) 計算開始 (B) 1 (A) 2 (C) 1 (B) 2 (A) 3 (D) 1 (C) 2 (B) 3 (A) 4 (E) 1 (D) 2 (C) 3 (B) 4 (A) 5 (F) 1 (E) 2 (D) 3 (C) 4 (B) 5 (A) 6 (A) 計算終了 (D) 4 (C) 5 (B) 6 (B) 計算終了 時間 ここだけ見ると、6クロックかかる処理を同時に6つ処理している → 一クロックで一回の計算ができているように見える (レイテンシの隠蔽) これを「スループット が1」と呼ぶ University of Tokyo
  • 26. 26/76 レイテンシとパイプライン (3/3) パイプライン数 一般的にはパイプラインは2本 Load/Storeも出せる場合は、IPCは最大4 ※ パイプライン パイプライン faddd fp2,fp0,fp1 計算開始 計算開始 fmuld fp3,fp1,fp4 計算中 計算中 計算中 計算中 計算中 計算中 計算中 計算中 計算中 計算中 計算終了 (fp2使用可) 計算終了 実質的に、1クロックで二つの計算が可能 → 2GHz × 2 = 4 GFLOPS University of Tokyo
  • 27. 27/76 積和(差)命令 fmaddd, fmsubd 積和、積差 積和   X = A*B+C 積差   Y = A*B-C アセンブラでは fmaddd fp0,fp1,fp2,fp3 # fp0 ← fp1*fp2+fp3 fmsubd fp0,fp1,fp2,fp3 # fp0 ← fp1*fp2+fp3 乗算一つ、加減算一つ、あわせて二つが(実質)1クロックで実行される。 そのパイプラインが二つあるので、あわせて1クロックで4つの演算 → 2GHz × 4 = 8 GFLOPS アセンブリにfmaddd,fmsubdが ずらずら並んでいなければダメ University of Tokyo
  • 28. 28/76 SIMD SIMDとは Single Instruction Multiple Data の略。通称シムド。 ベクトル命令のようなもの。 独立な同じ計算を同時に行う。 積和、積差のSIMD fmadd,s X1 = A1*B1+C1 , X2 = A2*B2+C2 を同時に実行 fmsub,s X1 = A1*B1-C1 , X2 = A2*B2-C2 を同時に実行 fmadd,sは、一つで4個の浮動小数点演算を行う。 「京」はこれが同時に二つ走る 4 * 2 * 2 GHz = 16GFlops (ピーク性能) アセンブリにfmaddd,s fmsubd,sが ずらずら並んでいなければダメ University of Tokyo
  • 29. 29/76 パイプラインのイメージ A A +B +B A-B A*B-C A1*B1+ A2*B2+ A*B+C C1 C2 A1*B1+ A2*B2+ A-B C1 C2 A1*B1+ A2*B2+ A*B+C C1 C2 A*B-C A-B ・幅が4、長さが6のベルトコンベアがある ・それぞれには、大きさ1、2、4の荷物を流せるが、同時に一つしか置けない ・ピーク性能比=ベルトコンベアのカバレージ ・ピーク性能を出す=なるべくおおきさ4の荷物を隙間無く流す (Intel系の命令パイプラインはやや異なる) University of Tokyo
  • 30. 30/76 計算機の仕組みのまとめ ・期待する性能がでない時、どこが問題かを調べるのに  計算機の知識が必要 (特にメモリアクセス) ・積和のパイプラインを持つCPUで性能を出すためには、  独立な積和演算がたくさん必要 ・SIMDを持つCPUで性能を出すためには、  独立なSIMD命令がたくさん必要  → 京やFX10では、独立な積和のSIMD命令がたくさん必要 アセンブリを読みましょう 変にプロファイラと格闘するより直接的です (-S 付きでコンパイルし、 fmadd,sなどでgrep) University of Tokyo
  • 32. 32/76 メモリ最適化(1/2) セル情報 相互作用粒子を探すさい、空間をセルに分割し、それぞれに登録する どの空間に粒子が存在するかを多次元配列で実装すると効率が悪い int GridParticleNumber[GridX][GridY]; int GridParticleIndex[GridX][GridY][GridMax]; 一次元配列実装 O(N) Partial Sort キャッシュ効率向上 レイテンシ University of Tokyo
  • 33. 33/76 メモリ最適化(2/2) 相互作用ペアリスト 短距離相互作用の場合、相互作用ペアリストを使う (Bookkeeping 法) 何も考えずに実装すると・・・ メモリ空間をランダムアクセスする(キャッシュ効率低下) 二つ分の粒子の情報をレジスタに持ってくる必要がある(要求バンド幅増大) 相互作用相手でソートする 相互作用粒子の一方がレジスタに載る データの読み込みが半分になる University of Tokyo
  • 34. 34/76 キャッシュ最適化 (1/2) 空間ソート 時間発展を続けると、空間的には近い粒子が、メモリ上では 遠くに保存されている状態になる → ソート University of Tokyo
  • 35. 35/76 キャッシュ最適化(2/2) 空間ソートの効果 ソートあり L2 Cache L3 Cache (256 KB) (8 MB) ソートなし 粒子数 ソートなし:粒子数がキャッシュサイズをあふれる度に性能が劣化する ソートあり:性能が粒子数に依存しない University of Tokyo
  • 36. 36/76 メモリ管理のまとめ CPUチューニングの前にメモリアクセスのチェックを とにかくキャッシュにのせる 連続アクセスにする (Partial Sortが有効) メモリアクセスの最適化は、計算機を選ばないことが多い  (CPUチューニングはアーキテクチャに強く依存する) 並列化の前にメモリアクセスの最適化をする ・メモリアクセスの最適化をすると、データの持ち方が変わる  →並列化の通信ルーチンが強く影響を受ける ・逆にNUMA最適化など、並列化をにらんだデータ構造を持つ必要もある  →要するになんども組み直す必要があるということ 必要なデータがほぼキャッシュに載っており、CPUの 計算待ちがほとんどになって初めてCPUチューニングへ University of Tokyo
  • 37. 37/76 CPUチューニング University of Tokyo
  • 38. 38/76 CPUチューニング PCで開発したコード、スパコンでの実行性能が すごく悪いんですが・・・ それ、条件分岐が原因かもしれません。 開発ではIntel系のCPUを使うことが多く、スパコンは 別のRISCタイプアーキテクチャを使うことが多い University of Tokyo
  • 39. 39/76 条件分岐コスト (1/2) 条件分岐なし 条件分岐あり void void calcforce(void){ calcforce(void){ for(int i=0;i<N-1;i++){ for(int i=0;i<N-1;i++){ for(int j=i+1;j<N;j++){ for(int j=i+1;j<N;j++){ const double dx = q[j][X] - q[i][X]; const double dx = q[j][X] - q[i][X]; const double dy = q[j][Y] - q[i][Y]; const double dy = q[j][Y] - q[i][Y]; const double dz = q[j][Z] - q[i][Z]; const double dz = q[j][Z] - q[i][Z]; const double r2 = (dx*dx + dy*dy + dz*dz); const double r2 = (dx*dx + dy*dy + dz*dz); const double r6 = r2*r2*r2; if (r2 > CUTOFF) continue; double df = (24.0*r6-48.0)/(r6*r6*r2)*dt; const double r6 = r2*r2*r2; p[i][X] += df*dx; double df = (24.0*r6-48.0)/(r6*r6*r2)*dt; p[i][Y] += df*dy; p[i][X] += df*dx; p[i][Z] += df*dz; p[i][Y] += df*dy; p[j][X] -= df*dx; p[i][Z] += df*dz; p[j][Y] -= df*dy; p[j][X] -= df*dx; p[j][Z] -= df*dz; p[j][Y] -= df*dy; } p[j][Z] -= df*dz; } } } } } 条件分岐により、必要な計算量は80%程度に減る University of Tokyo
  • 40. 40/76 条件分岐コスト (2/2) 条件分岐なし 経過時間[s] 条件分岐あり 条件分岐がなければIBM POWERの方がIntel Xeonより早いが 条件分岐があると、大幅に遅くなる IBM POWER、SPARC (京やFX10)は、条件分岐に弱い University of Tokyo
  • 41. 41/76 条件分岐削除 (1/2) 1.  foreach interacting particles 2.  r ← particle distance 3.  if distance > cutoff length then continue ここが重い 4.  f ← calculate force (次のループが回るかわからないから) 5.  p ← update momenta 6.  next 1.  foreach interacting particles 2.  r ← particle distance 3.  f ← calculate force 4.  if distance > cutoff length then f ←0 fsel 命令が使われる 5.  p ← update momenta (全てのループが確実にまわる) 6.  next 余計な計算量が増えるが、パイプラインがスムーズに流れる ために計算が早くなる(こともある) University of Tokyo
  • 42. 42/76 条件分岐削除 (2/2) 条件分岐なし 条件分岐あり 条件分岐削除 経過時間[s] IBM POWERでの実行が大幅に高速化された IBM POWERや、京には条件代入命令(fsel)がある fsel fp0,fp1,fp2,fp3 fp0 = (fp1 > 0)? fp2: fp3; これにより、マスク処理が可能 University of Tokyo
  • 43. 43/76 SIMD化 (1/4) SIMD化とは何か コンパイラが出力する命令のうち、SIMD命令の割合を増やす事 スカラ命令: 一度にひとつの演算をする SIMD命令(ベクトル命令):複数の対象にたいして、同種の演算を一度に行う 実際にやること コンパイラがSIMD命令を出しやすいようにループを変形する SIMD命令が出しやすいループ:  演算に依存関係がすくないループ コンパイラがどうしてもSIMD命令を出せなかったら? 手作業によるSIMD化 ほとんどアセン (Hand-SIMDize) ブリで書くよう なものです University of Tokyo
  • 44. 44/76 SIMD化 (2/4) ループアンローリング DO I = 1, N C[i] = A[i] + B[i] 依存関係があるのでSIMD命令が発行されない。 E[i] = C[i] + D[i] G[i] = E[i] + F[i] I[i] = G[i] + H[i] END DO ループを二倍展開し、独立な計算を作る (馬鹿SIMD化) コンパイラが A[1]+B[1] A[2]+B[2] Loop Unrolled x times C[1]+D[1] C[2]+D[2] とメッセージ出したらおそらくこれ E[1]+F[1] E[2]+F[2] 問題点: I[1]+G[1] I[2]+G[2] ・レイテンシを隠しづらい ・積和が作りにくい → 遅い University of Tokyo
  • 45. 45/76 SIMD化 (3/4) ソフトウェアパイプライニング DO I = 1, N ループインデックス C[i] = A[i] + B[i] E[i] = C[i] + D[i] A[1]+B[1] H[i] = F[i] + G[i] C[1]+D[1] A[2]+B[2] H[i] = H[i] + I[i] END DO E[1]+F[1] C[2]+D[2] A[3]+B[3] I[1]+G[1] E[2]+F[2] C[3]+D[3] A[4]+B[4] I[2]+G[2] E[3]+F[3] C[4]+D[4] I[3]+G[3] E[4]+F[4] I[4]+G[4] 独立な計算を増やしやすい レイテンシを隠し易い 人間の手でやるのはかなり厳しい だが、FX10ではこれをやらないと速度が出ない  →いかにコンパイラに「Loop software pipelined」を出させるか University of Tokyo
  • 46. 46/76 SIMD化 (4/4) 我々が実際にやったこと 作用反作用を使わない (二倍計算する)  → FX10ではメモリへの書き戻しがボトルネックだった ループを2倍展開した馬鹿SIMDループをさらに二倍アンロール (4倍展開)  → レイテンシ隠蔽のため、手でソフトウェアパイプライニング 局所一次元配列に座標データをコピー  → 運動量の書き戻しは行わないので、局所座標の読み出しがネックに  → 「グローバル、static配列でないとsoftware pipeliningできない」     というコンパイラの仕様に対応するため(もうなおったかも) 除算のSIMD化  → FX10には除算のSIMD命令がない(たぶん)  → 逆数近似命令(低精度)+精度補正コードを手で書いた。 チューニング成果 力の計算の速度は2倍に、全体でも30%程度の速度向上 University of Tokyo
  • 47. 47/76 CPUチューニングのまとめ CPU依存のチューニングは、当然のことながらCPUに依存する → CPUを変えるたびにチューニングしなおし → プログラムの管理も面倒になる そこまでやる必要あるんですか? 基本的には趣味の世界です。 世の中には全部intrinsic 命令でホットスポットを書く廃人もいるにはいる University of Tokyo
  • 48. 48/76 並列化、その前に University of Tokyo
  • 49. 49/76 並列化、その前に (1/3) 並列化とは何か? 複数のノードを使う事で、時間か空間を稼ぐ方法 時間を稼ぐ並列化 一つのコアあたりの計算量を減らすことで、計算規模をそのままに 計算時間を短くする (ストロングスケーリング) 空間を稼ぐ並列化 ひとつのノードでは扱えないような大きな問題を扱いたい ひとつのコアあたりの計算量はそのままに、コア数を増やすことで サイズを大きくする(ウィークスケーリング) University of Tokyo
  • 50. 50/76 並列化、その前に (2/3) 通信時間 通信時間には、レイテンシとバンド幅が関係 レイテンシ:通信がはじまるまでの時間 バンド幅:単位時間あたりどれだけのデータを通信できるか 並列化の粒度 計算時間と通信時間の比 計算 通信 Granularity が疎 (計算ドミナント)  大規模計算向き Granularity が密(通信ドミナント)  大規模計算が難しい ストロングスケーリング(計算規模をそのままにコア数を増やす) では、粒度が密になり、レイテンシが問題となる University of Tokyo
  • 51. 51/76 並列化、その前に (3/3) 現象と計算コスト 非平衡非定常系 平衡系、非平衡定常系 タイムスケールはサイズ依存性が弱い 緩和にかかる時間が系のサイズに依存 (核生成、音速、爆発) (遅い緩和を持つ現象はさらに厳しい) 粒子数と扱える現象 非平衡現象 平衡状態 論文としてpublishされたもの ベンチマーク (単一気泡生成) (気液相転移の臨界指数) 4.1G Particles 12M Particles 1.6M Particles 非平衡現象 今回紹介する計算 ベンチマーク (多重核生成) 38G Particles 1.4G Particles 同じ計算資源を使った場合、定常状態は非定常状態に比べてサイズが桁で落ちる 大規模計算では非平衡非定常系の計算が向いている ベンチマーク > 1 3桁 > 非平衡 > 1 2桁 > 平衡状態 University of Tokyo
  • 52. 52/76 並列化の方法 University of Tokyo
  • 54. 54/76 並列化の方法 (2/2) ・・・これだけではあんまりなので、注意点(心構え)を二点だけ 「並列化」の限界 既存のソースコードを「並列化」して得られる性能には限りがある 本当に大規模計算を志すなら、最初から「並列コード」を書くべき 最終的には何度も書き直すことになる ベンチマークからが勝負 計算科学においては、「科学論文を書くこと」が一応のゴール 大規模なベンチマークに成功しても、それだけでは論文が書けない 特に、観測ルーチンの並列化や、計算条件の調査に時間がかかる あとは並列化のノウハウを少し紹介 University of Tokyo
  • 55. 55/76 Flat MPIか、ハイブリッドか コア・CPU・ノード 複数のコアの集合→CPU ノード内はメモリ共有 複数のCPUの集合→ノード ノード間はメモリ分散 複数のノードの集合→スパコン OpenMPとMPI OpenMP 共有メモリ型並列スキーム (ノード内) ← スレッド MPI 分散メモリ型並列スキーム (ノード間) ← プロセス 一般に、Flat-MPIの方が早いが、メモリ消費も大きい 物性研 1024コア、コアあたり50万粒子 Flat-MPI: 1024 プロセス 276.5GB Hybrid: 128プロセス*8スレッド 199.1GB 全く同じ計算をしても、Flat-MPIではノードあたり 600MB程度利用メモリが増加する → 大規模計算ではMPI+OpenMPのハイブリッド並列必須 University of Tokyo
  • 56. 56/76 ハイブリッド並列化(1/6) スレッドとプロセス タスク プロセス プロセス プロセス メモリ空間 メモリ空間 メモリ空間 スレッド スレッド スレッド スレッド スレッド プロセス:OSから見た利用単位       ひとつ以上のスレッドと、プロセスごとに固有メモリ空間を持つ。 スレッド: CPUから見た利用単位。同じプロセス中のスレッドはメモリを共有する タスク: 人間から見た利用単位。 一つ以上のプロセスが協調して一つの仕事を実行する単位。 University of Tokyo
  • 57. 57/76 ハイブリッド並列化(2/6) スレッド並列 プロセス内で並列処理 ( ノード内並列) プロセス メモリ共有型 →排他制御が必要 メモリ空間 OpenMP、コンパイラの自動並列 スレッド スレッド 始めるのは簡単、性能を出すのは困難 スレッド スレッド プロセス並列 プロセス間で並列処理 ( ノード間並列) タスク メモリ分散型 プロセス プロセス →明示的通信が必要 MPIライブラリ メモリ空間 メモリ空間 敷居は高いが、性能予測はし易い 通信 スレッド スレッド ハイブリッド並列 スレッド スレッド プロセス並列とスレッド並列を両方やること 面倒くさい University of Tokyo
  • 58. 58/76 ハイブリッド並列化(3/6) 一般的方法 MPI: 空間分割 OpenMP: ループ分割 DO I=1,N ここか、 DO J in Pair(I) ここにスレッド並列をかける CalcForce(I,J) ENDDO ENDDO 問題点 運動量の書き戻しで同じ粒子にアクセスする可能性がある → テンポラリバッファを用意して衝突をさける → 作用反作用を使わない ペアリスト作成もスレッド並列化しなければならない 力の計算というボトルネックで、SIMD化とOpenMP化を同時に扱う必要がある University of Tokyo
  • 59. 59/76 ハイブリッド並列化(4/6) 完全空間分割 プロセス スレッド MPI: 空間分割 OpenMP: 空間分割 MDUnit MDUnit MDUnit MDUnit MDUnitクラス:  分割された領域を担当するクラス MDManagerクラス MDUnit MDUnit MDUnit MDUnit MDUnitを束ねて、通信をするクラス DO I=1,THREAD_NUM ここにスレッド並列をかける CALL MDUnit[i]->Calculate() ENDDO MDManager MDManager MPIプロセス = MDManager MDManagerがMDUnitを1つ担当 = Flat MPI 通信 MDManagerがMDUnitを複数担当=Hybrid MDUnit MDUnit MDUnit MDUnit MDUnit MDUnit MDUnit MDUnit University of Tokyo
  • 60. 60/76 ハイブリッド並列化(5/6) スレッドからのMPI通信 スレッドはプロセスより「軽い」かわりに、できることも限られる 例えば一般にスレッドからのMPI通信は許されて(実装されて)いない 以下の4種類の実装レベルが規定されている MPI_THREAD_SINGLE MPI_THREAD_FUNNELD スレッドの通信不可 メインスレッドからなら通信可 プロセス プロセス プロセス プロセス メモリ空間 メモリ空間 メモリ空間 メモリ空間 スレッド スレッド スレッド スレッド スレッド スレッド スレッド スレッド MPI_THREAD_SERIALIZED MPI_THREAD_MULTIPLE 同時に一つまでなら通信可能 (京、物性研) どのスレッドからでも自由に通信可 プロセス プロセス プロセス プロセス メモリ空間 メモリ空間 メモリ空間 メモリ空間 スレッド 1 スレッド スレッド スレッド スレッド 2 スレッド スレッド スレッド University of Tokyo
  • 61. 61/76 ハイブリッド並列化(6/6) 完全空間分割のメリット MDUnitクラスは、自分がスレッドであるかプロセスであるかを意識しなくてよい 二種類のロードバランスを考えなくてよい → Flat-MPIがスケールする領域であれば、ハイブリッドでもスケールする NUMA最適化を考えなくてよい(京、FX10では関係ない) 力の計算は、SIMD化のみ考えれば良い 完全空間分割のデメリット 通信が面倒くさい →処理系によっては、スレッドからのMPI通信が実装されていない →マスタースレッドにまとめて通信する必要がある 観測ルーチンを組むのが面倒くさい →通信がすべて二段になっているため University of Tokyo
  • 62. 62/76 MPIを使う際の注意点 小さいジョブが成功したのに大きなジョブが失敗・・・なぜ? MPIはリソースをかなり消費するから ノンブロッキング通信 直接通信 Process1 Process2 Buffer (heap) バッファ通信 Process1 Process2 ノンブロッキング通信はバッファを多く使うため、大きいジョブでメモリ不足に陥り易い (実はブロッキング通信を指定しても、ノンブロッキング通信が呼ばれる可能性がある) 典型的には「MPI_なんとか_MAX」が足りない、というエラーメッセージが良く出る。 対応する環境変数などを調べること。 対応策としては、通信を小分けにする、こまめにバッファをクリアするなど・・・ MPIの実装はベンダーに強く依存する。 あるシステムで問題なく動作したプログラムが他のところで動かない、ということはよくある University of Tokyo
  • 63. 63/76 馬鹿パラの是非 馬鹿パラとは 乱数の種やパラメータを変えたジョブを多数投入すること 自明並列(trivial parallelization)とも。 通信が発生しないため、見た目の並列化効率は100% やってはいけない馬鹿パラ 乱数の種を変えて、物理量の統計平均を稼ぐ馬鹿パラ 統計精度は、サンプル数の平方根に比例する したがって、100倍の計算資源をつぎ込んでも、 得られる精度向上は10倍程度→実質並列化効率10% 莫大なサンプル数による統計平均が必要なジョブを 超並列計算機で行う、というのは筋が悪い ※ パラメータ並列も拡張アンサンブルやGAを使うなど工夫したほうが良いと思う University of Tokyo
  • 64. 64/76 大規模計算では何ができるか 渡辺の研究紹介 University of Tokyo
  • 65. 65/76 気液混相流の全粒子計算 気液混相流 階層的モデリング マクロな輸送現象(熱、粒子、運動量)と 相転移 気泡間相互作用 流動現象 ミクロな相転移のカップルした非平衡状態 数値計算課題として マルチスケール、マルチフィジックス 境界の移動、生成、消滅 階層的モデリング スケールにより現象を分類 それぞれに支配方程式を仮定する 粒子間相互作用 ・人為的な階層定義 ・支配方程式の妥当性の検証 分子動力学法による全粒子計算 →大規模計算 Movie 全粒子計算 University of Tokyo
  • 66. 66/76 ベンチマーク (1/3) 計算の詳細 カットオフ 2.5、密度 0.5、初期条件: FCC、時間刻み: 0.001 積分法:二次のシンプレクティック 150ステップ後、1000ステップの計算にかかった時間を計測 東京大学情報基盤センター Oakleaf (FX10) 4800ノードを使って計測 (1.13ペタフロップス) 並列化 Flat MPI :16プロセス/node 最大 76800プロセス Hybrid: 16 スレッド/node  最大 4800プロセス、76800スレッド University of Tokyo
  • 67. 67/76 ベンチマーク (2/3) ウィークスケーリング (ノードあたりの計算量を固定したままノード数を増加) Flat MPIのスケーリングはほぼ完璧 Hybridの速度は不安定、かつFlat MPIの二倍程度遅い University of Tokyo
  • 68. 68/76 ベンチマーク (3/3) 4800 node 38.4G Particles 105229 MUPS (384億粒子) 1 node 8M Particles 22.7 MUPS MUPS: Million Updates Per Seconds ウィークスケーリング (ノードあたりの計算量を固定したままノード数を増加) 最大で4800ノード、76800プロセス、384億粒子 そろそろMUPSじゃなくてGUPSの領域 University of Tokyo
  • 69. 69/76 急減圧シミュレーション 計算の詳細 G Liquid Temperature 初期密度と温度: T=0.9, ρ=0.7 (純液相) 減圧強さ:一辺 1.025倍 (密度 0.7→0.65: 強減圧) 時間刻み:0.005 カットオフ:3.0 Coexistence 周期境界条件 数値積分法:二次のシンプレクティック(NVE)       二次のRESPA (NVT) 緩和: 1万ステップ トータルステップ数:  70万ステップ(ISSP)  18万ステップ(FX10) Density 計算の規模 物性研: 情報基盤センター: 1024プロセス 4800プロセス (76800スレッド) 320*320*320 1440*1200*1200 物性研の64倍 22937600粒子 1449776020粒子 70万ステップに10時間 18万ステップに15時間 Hybrid実行 Flat-MPI実行 Movie University of Tokyo
  • 70. 70/76 多重核生成からOstwald成長へ 物性研の計算結果 (2300万粒子) 初期ステージ 中間ステージ 最終ステージ 多重核生成 気泡間相互作用による「つぶしあい」 単一気泡へ収束 FX10の計算結果 (14億5千万粒子) 多重核生成から気泡間相互作用フェーズへ University of Tokyo
  • 71. 71/76 気泡の分布関数 (1/2) FX10 (L=1440) ISSP (L=320) 減圧後、一万ステップ後の気泡分布関数 (体積で規格化) → 気泡サイズの大きい領域で統計が取れていない University of Tokyo
  • 72. 72/76 気泡の分布関数 (2/2) ISSP (L=320) FX10 (L=1440) 減圧後、一万ステップ後の気泡分布スナップショット 初期ステージにおいても、気泡分布関数をきれいに 見るためには最低でも一億粒子は必要 University of Tokyo
  • 73. 73/76 ロードバランス 粒子系でのロードバランス 領域分割法における計算コストは、担当領域の粒子密度に比例 初期密度:0.7 → 減圧後: 0.65 →完璧なロードバランスが達成されたら、計算コストは0.65に比例 減圧後、気相と液相に分離 計算コスト 初期温度:0.9 → 減圧後: 0.88 この温度における共存密度 気相密度: 0.0344 実際のコスト 液相密度: 0.687 理想的な場合 毎ステップバリア同期を取っているため 計算速度は一番遅い領域が決める 一番遅い領域は、純液相領域 (密度0.687) プロセス1 プロセス2 プロセス3 プロセス4 プロセス5 ロードバランスの悪化 0.65 / 0.687 0.95 急減圧シミュレーションにおいては、ロードインバランスは問題にならない University of Tokyo
  • 74. 74/76 現象とスケール We are here 物理現象 Micro Macro 気泡生成 気泡流 多重気泡生成 (相転移と流動のカップリング) 必要粒子数 Linear Scale 10 nm 100 nm 1 um University of Tokyo
  • 75. 75/76 大規模計算でなにができたか ベンチマーク 最大4800ノード、76800プロセスで384億粒子の計算を実行 FX10向けのチューニングにより、ピーク性能比 17% (193TFLOPS) FlatMPIに比べてハイブリッド並列は遅く、かつ性能が安定しない しかし、ハイブリッド並列の方がメモリ消費は小さい 1ノードあたりのメモリ消費 Hybrid: 10GB/28GB 急減圧による多重気泡生成過程 FlatMPI: 14GB/28GB 14億粒子による急減圧シミュレーション 大規模ハイブリッドコードが15時間完走 76800コア×15時間 = 131コア年 → これだけ長時間破綻せずに走るためには事前の綿密なデバッグが不可欠 粒子間相互作用により気泡生成 気泡間相互作用によりOstwald的成長 マルチスケールな現象の直接計算に成功 University of Tokyo
  • 76. 76/76 全体のまとめ 高速化、並列化は好きな人がやればよい なぜなら科学とは好きなことをするものだから University of Tokyo