Upload
masayukitakagi
View
709
Download
0
Embed Size (px)
DESCRIPTION
introduce cl-cuda which is a library to use NVIDIA CUDA in Common Lisp
Citation preview
cl-cuda : a library to use NVIDIA CUDA in Common Lisp2014.7.29 Masayuki Takagi
Lisp Meet Up presented by Shibuya.lisp #19
1.GPGPU1.1.GPGPU(General Purpose GPU) とは?1.2.GPU の歴史1.3.スパコンへの浸透
3.cl-cuda ライブラリ3.1.cl-cuda の特徴3.2.使い方3.3.内部設計3.4.カーネル関数を起動するまでの流れ3.5.デモ3.6.パフォーマンス比較3.7.レポジトリ
2.NVIDIA CUDA2.1.CUDA とは?2.2.プロセッサ・アーキテクチャ2.3.メモリ・アーキテクチャ2.4.プログラミング・モデル
目次:
1.GPGPU
© 2014 Masayuki Takagi-2-
1.1.GPGPU(General Purpose GPU) とは?
GPU の計算資源を、画像処理以外の目的に応用する技術
© 2014 Masayuki Takagi-3-
1.2.GPUの歴史
3次元グラフィックスレンダリング
仮想空間に配置したモデルから、画面のピクセルの色をそれぞれ計算
VGA(640x480)の場合、独立した30万ピクセルの色を、60Hz(10-20msec)で処理する必要
グラフィックアクセラレータ(GPU)の登場
GPGPU に至るまでのGPUの歴史的背景を、簡単になぞります。
固定パイプライン - 1990's
物体表面での光や色の計算を、ハードウェアで実装
グローシェーディング、フォンシェーディング
プログラマブル・シェーダ - 2000's
物体表面での光や色の計算を、ソフトウェア的にプログラム可能に
バーテックスシェーダ、フラグメントシェーダ
General Purpose GPU - 2010's
汎用的に使えるんじゃね??
© 2014 Masayuki Takagi-4-
1.3.スパコンへの浸透
GPGPU は、スパコン分野にも広く浸透しています。
TOP 500, June 2014, Poster
2.NVIDIA CUDA
© 2014 Masayuki Takagi-6-
2.1.CUDA とは?
NVIDIA が提供する、並列計算アーキテクチャ。NVIDIA 製 GPU にて動作
GPUを利用したコプロセッシングによって、データ並列の計算処理能力を大幅に向上
C ベースの言語(CUDA C)、コンパイラ、デバッガ、プロファイラといった、ソフトウェア開発環境も包括的に提供
Kepler GK110 のチップ写真
© 2014 Masayuki Takagi-7-
2.2.プロセッサ・アーキテクチャ
CUDAでは、大量のプロセッサ・コアを、以下のような階層構造をとることで管理しています。
1つの GPU チップは、複数のストリーミング・マルチプロセッサ(SMX)からなる
1つのストリーミング・マルチプロセッサは、192 個の CUDA コアと1組のフロー・コントローラ、 L1 キャッシュからなる
複数のスレッドをまとめたスレッドブロックごとに、ストリーミング・マルチプロセッサで処理する
GTX 680 ブロック図(一部省略)
© 2014 Masayuki Takagi-8-
2.3.メモリ・アーキテクチャ
CUDAにおけるメモリは、プロセッサ・コアの階層構造に対応して、以下のような階層構造をとっています。
レジスタは、1つの CUDA コアからのみアクセス可能
シェアードメモリおよび L1 キャッシュは、同一の SMX に属する CUDA コア間で共有
L2 キャッシュは、SMX 間で共有される。小容量だが、オンチップにあり高速
グローバルメモリは、SMX 間で共有される。大容量だが、オフチップにあり低速
グローバルメモリ
L2 キャッシュ
シェアードメモリ / L1 キャッシュ
レジスタ
CUDA コア
ストリーミング・マルチプロセッサ(SMX)
GPU チップ
© 2014 Masayuki Takagi-9-
2.4.プログラミング・モデル
CUDA のプログラミング・モデルは、ハードウェアのアーキテクチャに対応した階層構造となっています。
C を拡張した CUDA C によって、カーネル関数を定義。CUDA スレッドを構成し、1つのCUDA コアで実行される。
スレッド数の指定とともに、カーネル関数を起動。スレッドブロックを構成し、1つのストリーミング・マルチプロセッサ(SMX)で実行される。
並列度が高く1つのスレッドブロックに収まらない場合、複数のスレッドブロックをまとめたグリッドを使い、複数の SMX で実行する。
3.cl-cuda ライブラリ
© 2014 Masayuki Takagi-11-
3.1.cl-cuda の特徴的な機能
cl-cuda は、Common Lisp から NVIDIA CUDA を使用するためのライブラリです。以下の機能を提供します。
カーネル関数の定義
カーネル記述言語
カーネルマクロの定義
カーネルモジュールの遅延コンパイル及び遅延ロード
CUDA コンテキストの管理
ホストメモリ及びデバイスメモリの管理
ホスト=デバイス間のメモリ転送
OpenGL 相互運用
© 2014 Masayuki Takagi-12-
3.2.使い方(1)
ここでは、cl-cuda の使い方を簡単に示します。
配列加算(vectorAdd)サンプル
2つの配列の各要素を足し合わせ、3つ目の配列に格納
各 CUDA コアが、配列の各要素を担当し、並列に処理
配列A
配列B
配列C
1 2 3
3 2 1
4 4 4+
© 2014 Masayuki Takagi-13-
3.2.使い方(2)
以下のようなコードで、Common Lisp から CUDA を使用できます。
(defkernel vec-‐add-‐kernel (void ((a float*) (b float*) (c float*) (n int))) (let ((i (+ (* block-‐dim-‐x block-‐idx-‐x) thread-‐idx-‐x))) (if (< i n) (set (aref c i) (+ (aref a i) (aref b i))))))
(defun main () (let* ((dev-‐id 0) (n 1024) (threads-‐per-‐block 256) (blocks-‐per-‐grid (/ n threads-‐per-‐block))) (with-‐cuda (dev-‐id) (with-‐memory-‐blocks ((a 'float n) (b 'float n) (c 'float n)) (random-‐init a n) (random-‐init b n) (sync-‐memory-‐block a :host-‐to-‐device) (sync-‐memory-‐block b :host-‐to-‐device) (vec-‐add-‐kernel a b c n :grid-‐dim (list blocks-‐per-‐grid 1 1) :block-‐dim (list threads-‐per-‐block 1 1)) (sync-‐memory-‐block c :device-‐to-‐host) (verify-‐result a b c n)))))
カーネル関数を定義
CUDA コンテキストを生成
ホストとデバイスに、メモリ領域を確保
ホストメモリからデバイスメモリへデータを転送
定義したカーネル関数を起動
デバイスメモリからホストメモリへデータを転送
© 2014 Masayuki Takagi-14-
3.3.内部設計
cl-cuda は、以下の3つのコンポーネントから構成されます。
cl-cuda.api実際にユーザが利用するインターフェイスを提供。defkernel マクロ、カーネルマネージャ、CUDA コンテキスト、メモリブロック、タイマ。
cl-cuda.langカーネル記述言語と、そのコンパイラを提供。コンパイラは、カーネル記述言語を CUDA C へ変換する。CUDAC から PTX ファイルへの変換は、cl-cuda.api のカーネルマネージャが管理する。
cl-cuda.driver-apiCUDA ドライバ API への FFI(ForeignFunction Interface)を提供。
© 2014 Masayuki Takagi-15-
3.4.カーネル関数を起動するまでの流れ
定義したカーネル関数を起動するまでの処理の流れは、以下のようになります。これらの処理は、カーネルマネージャによって管理され、コンパイルやロードは、必要なタイミングまで遅延して実行されます。
1. カーネル関数を定義defkenrel マクロを使用して、カーネル関数を定義します。
2. カーネル記述言語をコンパイルcl-cuda.lang のコンパイラを用いて、カーネル記述言語を CUDA C へコンパイルします。
3. CUDA C をコンパイルNVIDIA の提供する NVCC (NVIDIA CUDA Compiler)を呼び出し、CUDA C のコードをカーネルモジュール(PTX ファイル)へコンパイルします。
4. カーネルモジュールをロードCUDA ドライバ API を使用して、カーネルモジュールをロードします。
5. カーネル関数をロードCUDA ドライバ API を使用して、起動したいカーネル関数をロードします。
6. 引数として渡す値を配列に格納引数として GPU に渡す値を格納した配列を用意します。
7. カーネル関数を起動CUDA ドライバ API を使用して、カーネル関数を起動します。
© 2014 Masayuki Takagi-16-
3.5.デモ
Nbody シミュレーション
(:ql :cl-‐cuda-‐interop-‐examples)(cl-‐cuda-‐interop-‐examples.nbody:main :gpu t :interop t)
© 2014 Masayuki Takagi-17-
3.6.パフォーマンス比較
GPU を利用して並列計算することで、CPU での逐次処理に対し、40倍近い性能向上が得られました。
x37.5
Amazon EC2 インスタンス
プロセッサ
コア数
g2.2xlarge g2.2xlarge
Xeon E5-2670 2.6GHz NVIDIA GRID K520
1 コア(シングルスレッド、SIMD命令使用せず、gcc -O3相当)
1,536 コア
4.86[sec]
182.2[sec]
SPH(Smoothed Particle Hydrodynamics) による流体シミュレーション 11,774粒子
© 2014 Masayuki Takagi-18-
3.7.レポジトリ
cl-cuda は、GitHub から入手できます。Quicklispは、そのテストポリシーの都合上、登録不可でした。
https://github.com/takagi/cl-cuda/