Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

20190625 OpenACC 講習会 第1部

891 views

Published on

第23回 GPUコンピューティング講習会 - OpenACC講習会 -
http://gpu-computing.gsic.titech.ac.jp/node/97

Published in: Technology
  • Login to see the comments

20190625 OpenACC 講習会 第1部

  1. 1. 第1部 – Introduction to OpenACC Naruhiko Tan, Solution Architect, NVIDIA OPENACC 講習会
  2. 2. 本コースの目的 参加者のみなさんが、 OpenACC を用いてみなさん 自身のアプリケーションを加速 できるようにすること
  3. 3. 第1部のアウトライン カバーするトピック  OpenACC とは何か?  プロファイル駆動の開発  OpenACC の第一歩  例題  参考情報
  4. 4. INTRODUCTION TO OPENACC
  5. 5. アプリケーションを加速する3つの方法 アプリケーション ライブラリ 簡単に使える パフォーマンスが高い プログラミング言語 パフォーマンスが高い 柔軟性が高い 簡単に使える 移植性が高い コンパイラ ディレクティブ OpenACC
  6. 6. OPENACC とは… パフォーマンスと移植性 のために設計された、 ディレクティブ ベースの 並列プログラミング モデルです main() { <serial code> #pragma acc kernels { <parallel code> } } Add Simple Compiler Directive
  7. 7. OpenACC ディレクティブ データ移動の 管理 並列実行の 開始 ループ マッピングの 最適化 #pragma acc data copyin(a,b) copyout(c) { ... #pragma acc parallel { #pragma acc loop gang vector for (i = 0; i < n; ++i) { c[i] = a[i] + b[i]; ... } } ... } CPU, GPU, Manycore 移植性 相互操作可能 1つのソース コード 段階的
  8. 8. Single Source Low Learning CurveIncremental OPENACC 3つの利点
  9. 9. Incremental OPENACC - INCREMENTAL  既存の逐次処理コードを 維持。  指示行を追加し並列化。  結果の正しさを検証した 後に、さらに指示行を 追加。 Enhance Sequential Code #pragma acc kernels { for( i = 0; i < N; i++ ) { < loop code > } for( i = 0; i < N; i++ ) { < loop code > } } 既存の CPU 逐次処理 コードからはじめる。 OpenACC で並列化。 コードを再実行して動作確認、 必要に応じて OpenACC コードを 削除または修正。
  10. 10. Single Source Low Learning CurveIncremental OPENACC – 3つの利点  既存の逐次処理コードを 維持。  指示行を追加し並列化。  結果の正しさを検証した 後に、さらに指示行を 追加。
  11. 11. Single Source OPENACC – SINGLE SOURCE  異なるアーキテクチャ上で 同一のコードをリビルド。  特定のマシンでどのように 並列化するかはコンパイラ が決定。  逐次処理コードを維持。 NVIDIA GPU PEZY-SC POWER Sunway x86 CPU x86 Xeon Phi サポートされる プラットフォーム int main(){ ... for(int i = 0; i < N; i++) < loop code > } int main(){ ... #pragma acc kernels for(int i = 0; i < N; i++) < loop code > } コンパイラは OpenACC ディレクティブを 無視できるので、同一のコードを 逐次・並列実行に利用可能。
  12. 12. Single Source Low Learning CurveIncremental OPENACC – 3つの利点  既存の逐次処理コードを 維持。  指示行を追加し並列化。  結果の正しさを検証した 後に、さらに指示行を 追加。  異なるアーキテクチャ上で 同一のコードをリビルド。  特定のマシンでどのように 並列化するかはコンパイラ が決定。  逐次処理コードを維持。
  13. 13. Low Learning Curve OPENACC – LOW LEARNING CURVE  OpenACC は簡単に 使えて、簡単に学べる。  プログラマは慣れ親しんだ C/C++, Fortran を利用。  ハードウェアの詳細 については学習不要。 int main(){ <sequential code> #pragma acc kernels { <parallel code> } } コンパイラ ヒント CPU Parallel Hardware プログラマは、コードの どの部分を並列化するか について、コンパイラに ヒントを与える。 コンパイラはターゲットの ハードウェア向けに並列化。
  14. 14. Single SourceIncremental OPENACC – 3つの利点 Low Learning Curve  OpenACC は簡単に 使えて、簡単に学べる。  プログラマは慣れ親しんだ C/C++, Fortran を利用。  ハードウェアの詳細 については学習不要。  既存の逐次処理コードを 維持。  指示行を追加し並列化。  結果の正しさを検証した 後に、さらに指示行を 追加。  異なるアーキテクチャ上で 同一のコードをリビルド。  特定のマシンでどのように 並列化するかはコンパイラ が決定。  逐次処理コードを維持。
  15. 15. GAUSSIAN 16 Using OpenACC allowed us to continue development of our fundamental algorithms and software capabilities simultaneously with the GPU-related work. In the end, we could use the same code base for SMP, cluster/ network and GPU parallelism. PGI's compilers were essential to the success of our efforts. Mike Frisch, Ph.D. President and CEO Gaussian, Inc.
  16. 16. VASP For VASP, OpenACC is the way forward for GPU acceleration. Performance is similar and in some cases better than CUDA C, and OpenACC dramatically decreases GPU development and maintenance efforts. We’re excited to collaborate with NVIDIA and PGI as an early adopter of CUDA Unified Memory. Prof. Georg Kresse Computational Materials Physics University of Vienna
  17. 17. GTC Using OpenACC our scientists were able to achieve the acceleration needed for integrated fusion simulation with a minimum investment of time and effort in learning to program GPUs. Zhihong Lin Professor and Principal Investigator UC Irvine Head Shot
  18. 18. OPENACC の構文
  19. 19. OPENACC の構文  C/C++ での pragma は、どのようにコードをコンパイルするかをコンパイラに指示する。コンパイラが その pragma を解釈できない場合は、無視される。  Fortran での directive は、どのようにコードをコンパイルするかをコンパイラに指示する特別な書 式のコメントで、コンパイラが解釈できない場合は 無視される。  “acc” はその後に OpenACC ディレクティブが続くことをコンパイラに知らせる。  Directives はコードを変換するための OpenACC のコマンド。  Clauses はディレクティブに加えてコードの変更を指示する。 コード中での OpenACC 構文の利用 C/C++ #pragma acc directive clauses <code> Fortran !$acc directive clauses <code>
  20. 20. 例題
  21. 21. ラプラス方程式 熱拡散方程式 Very Hot Room Temp ここでは、金属板上の単純な 温度分布シミュレーションを考える。 金属板の上方境界がある 一定温度に保たれるとする。 金属板の温度分布をシミュレートする。
  22. 22. 例:JACOBI ITERATION  隣接する格子点の平均から注目格子点の値の更新を反復的に繰り返すことにより、 収束解を得る(e.g. 温度)。  一般的で有用なアルゴリズム。  例 : 2D のラプラス方程式を解く: 𝛁𝛁𝟐𝟐 𝒇𝒇(𝒙𝒙, 𝒚𝒚) = 𝟎𝟎 A(i,j) A(i+1,j)A(i-1,j) A(i,j-1) A(i,j+1) 𝐴𝐴𝑘𝑘+1 𝑖𝑖, 𝑗𝑗 = 𝐴𝐴𝑘𝑘(𝑖𝑖 − 1, 𝑗𝑗) + 𝐴𝐴𝑘𝑘 𝑖𝑖 + 1, 𝑗𝑗 + 𝐴𝐴𝑘𝑘 𝑖𝑖, 𝑗𝑗 − 1 + 𝐴𝐴𝑘𝑘 𝑖𝑖, 𝑗𝑗 + 1 4
  23. 23. JACOBI ITERATION: C 言語 while ( err > tol && iter < iter_max ) { err=0.0; for( int j = 1; j < n-1; j++) { for( int i = 1; i < m-1; i++ ) { Anew[OFFSET(j, i, m)] = 0.25 * ( A[OFFSET(j, i+1, m)] + A[OFFSET(j, i-1, m)] + A[OFFSET(j-1, i, m)] + A[OFFSET(j+1, i, m)]); error = fmax( error, fabs(Anew[OFFSET(j, i, m)] - A[OFFSET(j, i , m)])); } } for( int j = 1; j < n-1; j++) { for( int i = 1; i < m-1; i++ ) { A[OFFSET(j, i, m)] = Anew[OFFSET(j, i, m)]; } } iter++; } 収束するまで反復 配列要素のループ 近傍の値から注目点の値を更 新 収束判定のための最大誤差を 計算 input/output 配列をス ワップ
  24. 24. プロファイル駆動の開発
  25. 25. OPENACC による開発サイクル  分析 - コードを分析し、並列化や最適 化が必要と思われる箇所を見出す。  並列化 - 最も処理に時間がかかる箇所 からコードの並列化を行う。計算結果が正 しいことも確認する。  最適化 – 並列化によって得られた性能 から、さらなる高速化を図る。 分析 並列化最適化 分析
  26. 26. コードがどのように実行されたかの 詳細な情報を取得 シリアル コードの プロファイリング コードのプロファイリング 例えば以下のような情報を含む:  総実行時間  個々のルーチンの実行時間  ハードウェア カウンタ 最も処理時間がかかっている箇所を 特定する。それらの “ホットスポット” に 注目して並列化を行う 例題: ラプラス方程式 Total Runtime: 39.43 seconds calcNext 21.49s swap 19.04s
  27. 27. シリアル コードのプロファイリング はじめての NVIDIA Visual Profiler  単純なシリアル コードをプロファイリング。  シリアル コードは CPU で実行される。  コードがどのように実行されたかを確認す るには、”CPU Details” タブを選択。
  28. 28. シリアル コードのプロファイリング CPU Details  “CPU Details” タブでは、コードのどの箇 所が、どのくらい実行時間がかかっている か、を確認できる。  タブの右上に位置している、3つの表示オ プションで確認することができる。  それらを展開することで、さらに詳細を表 示することもできる。
  29. 29. シリアル コードのプロファイリング CPU Details  実行時間の大半を占めている2箇所を 特定することができる。  “calcNext” 関数で 21.49 秒。  memcpy 関数で 19.04 秒。  _c_mcopy8 は、”swap” 関数に適用さ れた、コンパイラによる最適化。
  30. 30. シリアル コードのプロファイリング PGPROF (NVPROF)  “CPU Details” タブでは、該当箇所をダ ブル クリックすることで、関連するソース コードを開くことができる。  ここでは、 “calcNext:37” を選択した結 果、ソース コードが開かれ37行目がハイ ライトされている。
  31. 31. OPENACC PARALLEL LOOP ディレクティブ
  32. 32. OPENACC PARALLEL ディレクティブ 並列性の表現 #pragma acc parallel { } parallel ディレクティブに 到達すると、コンパイラは 重複して実行される1つ以 上の並列 gangs を生成 する。 gang gang gang gang gang gang
  33. 33. #pragma acc parallel { } #pragma acc parallel { for(int i = 0; i < N; i++) { // Do Something } } OPENACC PARALLEL ディレクティブ 並列性の表現 このループは各 gang で 重複して実行される。 gang gang gang gang gang gang loop loop loop loop loop loop loop
  34. 34. #pragma acc parallel { for(int i = 0; i < N; i++) { // Do Something } } OPENACC PARALLEL ディレクティブ 並列性の表現 #pragma acc parallel { } つまり、各 gang は このループ全体を実行する。 gang gang gang gang gang gang
  35. 35. OPENACC PARALLEL ディレクティブ 単一ループの並列化  並列実行したい領域を parallel ディレクティブによって 指定する。  この parallel 領域は、C/C++ では中括弧 { } で、 Fortran では start と end で指定される。  loop ディレクティブは、直後のループの反復計算を、並 列 gang 上で並列実行するようコンパイラに指示する。 C/C++ #pragma acc parallel { #pragma acc loop for(int i = 0; j < N; i++) a[i] = 0; } Fortran !$acc parallel !$acc loop do i = 1, N a(i) = 0 end do !$acc end parallel
  36. 36. OPENACC PARALLEL ディレクティブ 単一ループの並列化  これら (parallel, loop) は 1行にまとめて使われること が多い。  この例では、parallel loop ディレクティブは直後のルー プに適用される。  このディレクティブは、並列実行とループの反復計算を 分散させる領域を一度に指定する。  parallel loop をデータ依存性のあるループに適用する と、正しく計算されない可能性がある。 C/C++ #pragma acc parallel loop for(int i = 0; j < N; i++) a[i] = 0; Fortran !$acc parallel loop do i = 1, N a(i) = 0 end do
  37. 37. #pragma acc parallel { for(int i = 0; i < N; i++) { // Do Something } } OPENACC PARALLEL ディレクティブ 並列性の表現 #pragma acc parallel { #pragma acc loop for(int i = 0; i < N; i++) { // Do Something } } loop ディレクティブは、 並列化されるループを 指示する。
  38. 38. OPENACC PARALLEL LOOP ディレクティブ 複数ループの並列化  並列化のためには、各ループの直前に parallel loop ディレクティブを挿入する必要がある。  各 parallel loop ディレクティブは、それぞれ異なるルー プ境界や最適化の適用が可能。  各 parallel loop は、それぞれ異なる方法で並列化さ れ得る。  複数ループの並列化に際しては、この方法を推奨。複 数ループを同一の parallel 領域で並列化を行うと、 パフォーマンスの悪化や、予期しない結果を引き起こす 場合がある。 #pragma acc parallel loop for(int i = 0; i < N; i++) a[i] = 0; #pragma acc parallel loop for(int j = 0; j < M; j++) b[j] = 0;
  39. 39. while ( err > tol && iter < iter_max ) { err=0.0; #pragma acc parallel loop reduction(max:err) for( int j = 1; j < n-1; j++) { for( int i = 1; i < m-1; i++ ) { Anew[OFFSET(j, i, m)] = 0.25 * ( A[OFFSET(j, i+1, m)] + A[OFFSET(j, i-1, m)] + A[OFFSET(j-1, i, m)] + A[OFFSET(j+1, i, m)]); error = fmax( error, fabs(Anew[OFFSET(j, i, m)] - A[OFFSET(j, i , m)])); } } #pragma acc parallel loop for( int j = 1; j < n-1; j++) { for( int i = 1; i < m-1; i++ ) { A[OFFSET(j, i, m)] = Anew[OFFSET(j, i, m)]; } } iter++; } OPENACC PARALLEL LOOP による並列化 43 最初のループを並列化 max reduction を指定 2つ目のループを並列化 どのループを並列化するかのみを指示し、 どのように並列化するかの詳細は指示 していない。
  40. 40. REDUCTION クローズ  reduction クローズは、複数の配列要素の値を1つの スカラーに ”縮約” する。例えば、配列要素の和や最 大値など。  それぞれのスレッドがそれぞれの部分を計算する。  コンパイラが最終的な縮約を行い、指定されたオペレー タにもとづいて、1つのグローバルな結果を生成する。 for( i = 0; i < size; i++ ) for( j = 0; j < size; j++ ) double tmp = 0.0f; #pragma parallel acc loop ¥ reduction(+:tmp) for( k = 0; k < size; k++ ) tmp += a[i][k] * b[k][j]; c[i][j] = tmp; for( i = 0; i < size; i++ ) for( j = 0; j < size; j++ ) for( k = 0; k < size; k++ ) c[i][j] += a[i][k] * b[k][j];
  41. 41. REDUCTION クローズのオペレータ Operator Description Example + Addition/Summation reduction(+:sum) * Multiplication/Product reduction(*:product) max Maximum value reduction(max:maximum) min Minimum value reduction(min:minimum) & Bitwise and reduction(&:val) | Bitwise or reduction(|:val) && Logical and reduction(&&:val) || Logical or reduction(||:val)
  42. 42. コードのビルドと実行
  43. 43. PGI コンパイラの基本  C コードをコンパイルするコマンドは ‘pgcc’。  C++ コードをコンパイルするコマンドは ‘pgc++’。  Fortran コードをコンパイルするコマンドは ‘pgfortran’。  -fast は、最適化を行うようコンパイラに指示するフラグ。 pgcc, pgc++ and pgfortran $ pgcc –fast main.c $ pgc++ -fast main.cpp $ pgfortran –fast main.F90
  44. 44. PGI コンパイラの基本  -Minfo フラグは、コンパイルされたコードについてのフィードバックを表示するよう、コンパイラに指示 する。  -Minfo=accel はコードのどの部分が OpenACC によって加速されたかに関する情報を表示する。  -Minfo=opt は全ての最適化に関する情報を表示する。  -Minfo=all は全てのフィードバックを表示する。 -Minfo flag $ pgcc –fast –Minfo=all main.c $ pgc++ -fast -Minfo=all main.cpp $ pgfortran –fast –Minfo=all main.f90
  45. 45. PGI コンパイラの基本  -ta フラグは OpenACC コードをある “Target Accelerator” (TA) 向けにビルドするよう指示す る。  -ta=multicore – マルチコア CPU のスレッド並列向けにコードをビルド。  -ta=tesla:managed – NVIDIA (Tesla) GPU 向けにコードをビルドし、データ移動をコンパイラが 管理するよう指示(詳細は後ほど)。 -ta flag $ pgcc –fast –Minfo=accel –ta=tesla:managed main.c $ pgc++ -fast -Minfo=accel –ta=tesla:managed main.cpp $ pgfortran –fast –Minfo=accel –ta=tesla:managed main.f90
  46. 46. コードをビルド (マルチコア) 50 $ pgcc -fast -ta=multicore -Minfo=accel laplace2d_uvm.c main: 63, Generating Multicore code 64, #pragma acc loop gang 64, Accelerator restriction: size of the GPU copy of Anew,A is unknown Generating reduction(max:error) 66, Loop is parallelizable 74, Generating Multicore code 75, #pragma acc loop gang 75, Accelerator restriction: size of the GPU copy of Anew,A is unknown 77, Loop is parallelizable
  47. 47. OPENACC による高速化 1.00X 3.05X 0.00X 0.50X 1.00X 1.50X 2.00X 2.50X 3.00X 3.50X SERIAL MULTICORE Speed-Up Speed-up PGI 18.7, NVIDIA Tesla V100, Intel i9-7900X CPU @ 3.30GHz
  48. 48. コードをビルド (GPU) 52 $ pgcc -fast -ta=tesla:managed -Minfo=accel laplace2d_uvm.c main: 63, Accelerator kernel generated Generating Tesla code 64, #pragma acc loop gang /* blockIdx.x */ Generating reduction(max:error) 66, #pragma acc loop vector(128) /* threadIdx.x */ 63, Generating implicit copyin(A[:]) Generating implicit copyout(Anew[:]) Generating implicit copy(error) 66, Loop is parallelizable 74, Accelerator kernel generated Generating Tesla code 75, #pragma acc loop gang /* blockIdx.x */ 77, #pragma acc loop vector(128) /* threadIdx.x */ 74, Generating implicit copyin(Anew[:]) Generating implicit copyout(A[:]) 77, Loop is parallelizable
  49. 49. OPENACC による高速化 1.00X 3.05X 37.14X 0.00X 5.00X 10.00X 15.00X 20.00X 25.00X 30.00X 35.00X 40.00X SERIAL MULTICORE NVIDIA TESLA V100 Speed-Up Speed-up PGI 18.7, NVIDIA Tesla V100, Intel i9-7900X CPU @ 3.30GHz
  50. 50. おわりに
  51. 51. KEY CONCEPTS 第1部で学んだこと  OpenACC とは何か。  より良いコードを書くために、プロファイル駆動のプログラミングがどのように役立つか。  計算時間短縮のための、OpenACC の parallel loop ディレクティブの使い方。 第2部で学ぶこと:  OpenACC でデータ移動を管理する。
  52. 52. Resources https://www.openacc.org/resources Success Stories https://www.openacc.org/success- stories Events https://www.openacc.org/events OPENACC RESOURCES Guides ● Talks ● Tutorials ● Videos ● Books ● Spec ● Code Samples ● Teaching Materials ● Events ● Success Stories ● Courses ● Slack ● Stack Overflow Compilers and Tools https://www.openacc.org/tools FREE Compilers

×