Cuda

1,337 views
1,214 views

Published on

cuda

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,337
On SlideShare
0
From Embeds
0
Number of Embeds
35
Actions
Shares
0
Downloads
29
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Cuda

  1. 1. CUDA 東京工業大学 4年 千葉 滋 研究室 穂積 俊平 1
  2. 2. CUDA 【NVIDIA】の 【GPU】に対する、 【GPGPU】を目的とした 統合開発環境 2
  3. 3. NVIDIA •  本社:アメリカ合衆国カリフォルニア州サンタクララ •  主な製品:GPU •  ライバル: VS. 3
  4. 4. NVIDIA •  本社:アメリカ合衆国カリフォルニア州サンタクララ •  主な製品:GPU •  ライバル:AMD VS. 4
  5. 5. NVIDIA •  本社:アメリカ合衆国カリフォルニア州サンタクララ •  主な製品:GPU •  ライバル:AMD VS. CUDAはNVIDIAのGPUでのみ動作する! 5
  6. 6. GPU コンピュータにおける画像処理の需要の高まり 6
  7. 7. GPU コンピュータにおける画像処理の需要の高まり 画像処理専用のプロセッサを作ろう 7
  8. 8. GPU コンピュータにおける画像処理の需要の高まり 画像処理専用のプロセッサを作ろう GPUの誕生!!!!! 8
  9. 9. GPUのアーキテクチャ SM : SPを複数個含む SP : 最小単位の演算処理ユニット SM ビデオカード GPU SP SP SM SM SP SP ビデオメモリ 9
  10. 10. GPUとCPUの違い •  SMはSIMDで動作する。 10
  11. 11. GPUとCPUの違い •  SMはSIMDで動作する。 Single Instruction Multi Data 11
  12. 12. GPUとCPUの違い •  SMはSIMDで動作する。 Single Instruction Multi Data SM内のSPは異なる処理をする事はできない。 12
  13. 13. GPUのアーキテクチャ どのくらいの演算処理ユニット(SP)があるのか?    13
  14. 14. GPUのアーキテクチャ どのくらいの演算処理ユニット(SP)があるのか? 比較対象:Intel Corei7 HyperThreadingが4つ。実質8個    14
  15. 15. GPUのアーキテクチャ どのくらいの演算処理ユニット(SP)があるのか? 比較対象:Intel Corei7 HyperThreadingが4つ。実質8個 例:GT200   15
  16. 16. GPUのアーキテクチャ どのくらいの演算処理ユニット(SP)があるのか? 比較対象:Intel Corei7 HyperThreadingが4つ。実質8個 例:GT200   SM数30個 16
  17. 17. GPUのアーキテクチャ どのくらいの演算処理ユニット(SP)があるのか? 比較対象:Intel Corei7 HyperThreadingが4つ。実質8個 例:GT200   SM数30個   各SMに含まれるSPの数8個 30×8 = 17
  18. 18. GPUのアーキテクチャ どのくらいの演算処理ユニット(SP)があるのか? 比較対象:Intel Corei7 HyperThreadingが4つ。実質8個 例:GT200   SM数30個   各SMに含まれるSPの数8個 30×8 = 240個 18
  19. 19. GPUのアーキテクチャ どのくらいの演算処理ユニット(SP)があるのか? 比較対象:Intel Corei7 HyperThreadingが4つ。実質8個 例:GT200   SM数30個   各SMに含まれるSPの数8個 30×8 = 240個 30倍 19
  20. 20. GPGPU GPUの演算処理能力はとても高い 20
  21. 21. GPGPU GPUの演算処理能力はとても高い より汎用的な目的でGPUを使おう! 21
  22. 22. CUDA 【NVIDIA】の 【GPU】に対する、 【GPGPU】を目的とした 統合開発環境 22
  23. 23. CUDA CUDAはCPUとGPU両方扱う! o  CPU => ホスト o  GPU => デバイス 23
  24. 24. CUDA CUDAはCPUとGPU両方扱う! o  CPU => ホスト o  GPU => デバイス ホストとデバイスの間で通信が必要 24
  25. 25. 典型的な処理の流れ 1.  デバイスメモリ上に領域を確保2.  データをホストメモリからデバイスメモリにコピー3.  GPUで処理を実行4.  結果をデバイスメモリからホストメモリにコピー GPU CPU デバイスメモリ ホストメモリ 25
  26. 26. 典型的な処理の流れ 1.  デバイスメモリ上に領域を確保2.  データをホストメモリからデバイスメモリにコピー3.  GPUで処理を実行4.  結果をデバイスメモリからホストメモリにコピー GPU CPU デバイスメモリ ホストメモリ 26
  27. 27. 典型的な処理の流れ 1.  デバイスメモリ上に領域を確保2.  データをホストメモリからデバイスメモリにコピー3.  GPUで処理を実行4.  結果をデバイスメモリからホストメモリにコピー GPU CPU デバイスメモリ ホストメモリ 27
  28. 28. 典型的な処理の流れ 1.  デバイスメモリ上に領域を確保2.  データをホストメモリからデバイスメモリにコピー3.  GPUで処理を実行4.  結果をデバイスメモリからホストメモリにコピー GPU CPU デバイスメモリ ホストメモリ 28
  29. 29. 典型的な処理の流れ 1.  デバイスメモリ上に領域を確保2.  データをホストメモリからデバイスメモリにコピー3.  GPUで処理を実行4.  結果をデバイスメモリからホストメモリにコピー GPU CPU デバイスメモリ ホストメモリ 29
  30. 30. 実際のCUDAコード 例  for(int i = 0;i < 1024;i++){ C[i] = A[i] + B[i]; } 30
  31. 31. 実際のCUDAコード 1.  デバイスメモリ上に領域を確保 31
  32. 32. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N) 32
  33. 33. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N)2.  データをホストメモリからデバイスメモリにコピー 33
  34. 34. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N)cudaMemcpy(A_d,A_h,sizeof(float)*N,hostToDevise) 34
  35. 35. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N)cudaMemcpy(A_d,A_h,sizeof(float)*N,hostToDevise)3.  GPUで処理を実行 35
  36. 36. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N)cudaMemcpy(A_d,A_h,sizeof(float)*N,hostToDevise)dim3 Dg(2,1,1) Db(512,1,1)vec_add<<Dg,Db>>(A_d,B_d,C_d) 36
  37. 37. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N)cudaMemcpy(A_d,A_h,sizeof(float)*N,hostToDevise)dim3 Dg(2,1,1) Db(512,1,1)vec_add<<Dg,Db>>(A_d,B_d,C_d)4.  結果をデバイスメモリからホストメモリにコピー 37
  38. 38. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N)cudaMemcpy(A_d,A_h,sizeof(float)*N,hostToDevise)dim3 Dg(2,1,1) Db(512,1,1)vec_add<<Dg,Db>>(A_d,B_d,C_d)cudaMemcpy(C_h,C_d,sizeof(float)*N,deviseToHost) 38
  39. 39. 実際のCUDAコード float *A_d, *B_d, *C_dcudaMalloc(&A_d,sizeof(float)*N)cudaMemcpy(A_d,A_h,sizeof(float)*N,hostToDevise)dim3 Dg(2,1,1) Db(512,1,1)vec_add<<<Dg,Db>>>(A_d,B_d,C_d)cudaMemcpy(C_h,C_d,sizeof(float)*N,deviseToHost)dim3って何?vec_addの中身は? 39
  40. 40. CUDAにおけるスレッド管理 •  グリッドとブロックという概念を導入し、3次元的にス レッドを管理している。 グリッド ブロック ブロック ブロック ブロック 40
  41. 41. CUDAにおけるスレッド管理 •  グリッドとブロックという概念を導入し、3次元的にス レッドを管理している。 グリッド ブロック ブロック ブロック ブロック •  dim3変数はグリッド、ブロックのサイズを指定している。 o  Dg(2,1,1) Db(512,1,1) 41
  42. 42. カーネル関数 __global__ void vec_add(float *A_d, *B_d, *C_d){ int i = blockDim.x*blockIdx.x + threadIdx.x; C_d[i] = A_d[i] + B_d[i]; } 42
  43. 43. カーネル関数 __global__ void vec_add(float *A_d, *B_d, *C_d){ int i = blockDim.x*blockIdx.x + threadIdx.x; C_d[i] = A_d[i] + B_d[i]; } ビルトイン変数 カーネル関数内で宣言せずに使用できる変数 blockDim : blockの大きさの情報blockIdx : 何番目のblockを参照しているかthreadIdx : 何番目のthreadを参照しているか 43
  44. 44. カーネル関数 __global__ void vec_add(float *A_d, *B_d, *C_d){ int i = blockDim.x*blockIdx.x + threadIdx.x; C_d[i] = A_d[i] + B_d[i]; } ビルトイン変数 カーネル関数内で宣言せずに使用できる変数 blockDim : blockの大きさの情報blockIdx : 何番目のblockを参照しているかthreadIdx : 何番目のthreadを参照しているか 各スレッドと配列の要素を結びつけている。 44
  45. 45. CUDA4.1 •  LLVMをベースにしたコンパイラを導入 o  最大で10%の速度アップ •  自動でパフォーマンス測定を行うVisual Profiler •  CUDA_GDB o  カーネル関数におけるデバッグ、アサート •  CUDA_MEMCHECK o  カーネル関数におけるアウトオブバウンズを検知 45

×