複数のデバイスにおける CUDALink
Mathematica 言語の中核である関数型,およびリスト志向の特性により,CUDALink は組込みの即時データ並列化が提供でき,利用できるGPUカードに自動的に計算を分配する.
はじめに
まず CUDALink アプリケーションをロードする.
デバイス数と同じだけワーカーカーネルを開始する.
| Out[2]= |  |
$CUDADeviceCountはシステム上のデバイス数である.
$CUDADeviceCountはシステム上のCUDA GPUデバイス数を取得する
CUDALink を全ワーカーカーネル上にロードする.
CUDALink は既存の Mathematica 並列計算機能を使って複数のGPU上で実行する.このセクションでは,以下の関数を使う.
CUDALink は Mathematica の並列計算機能で複数のGPUを使う
すべてのカーネル上の$CUDADevice変数を設定する.
| Out[4]= |  |
CUDALink 関数
画像処理,線形代数,高速フーリエ(Fourier)変換等の高レベル CUDALink 関数は他の Mathematica 関数と同様に異なるカーネルで使用できる.違いは,$CUDADeviceが計算が行われるデバイスに設定されるということだけである.
画像の名前をExampleDataの
データ集合から取られるように設定する.
変数
をワーカーカーネルに分配する.
| Out[6]= |  |
ExampleDataから取られた画像にCUDAErosionを適用する.
| Out[7]= |  |
速度が2倍改善されたことに注目されたい.これらの画像は小さく,データは転送されなければならないので,パフォーマンスは4倍は上がらない.
| Out[8]= |  |
その他の場合は,データの転送にかかる時間は計算に必要な時間に比べると多くない.ここでは2000のランダムな整数ベクトルを割り当てる.
各デバイスにCUDAFoldをマップする.
| Out[10]= |  |
より速度が上がった.
| Out[11]= |  |
CUDALink プログラミング
CUDAFunctionは最適化されており,GPUに局所的であるため,DistributeDefinitionsを使ってワーカーカーネルと共有することはできない.このセクションではGPUをプログラムする別の方法を述べる.
2を足す
ベクトルに2を足す基本的なCUDAコードをロードする.
CUDAFunctionをロードする.割当てにSetDelayedが使われている.これにより,DistributeDefinitionsはCUDAFunctionLoad呼出しのすべての従属変数を分配することができる.
入力パラメータを設定する.
ワーカーカーネル間に定義を分配する.
| Out[17]= |  |
異なるCUDAデバイスを使って各ワーカーカーネルでCUDAFunctionを実行する.
| Out[18]= |  |
最初の20要素を示す結果を集める.
| Out[19]= |  |
マンデルブロ(Mandelbrot)集合
これは CUDALink ドキュメントの別のセクションで定義されたものと同じCUDAコードである.
CUDAFunctionをロードする.
ワーカーカーネルと変数を共有する.
| Out[10]= |  |
それぞれ異なるズームレベルでカーネルを開始し,
画像を返す.
| Out[24]= |  |
乱数生成器
以下のファイルにメルセンヌツイスタ(Mersenne Twister)が実装されている.
| Out[25]= |  |
関数を Mathematica にロードする.
CUDAFunctionのための入力変数を設定する.
関数と入力パラメータをを分配する.
| Out[32]= |  |
シードの値を割り当てる.乱数が相関性を持たないようにするために,シードの評価は各ワーカーカーネルで行われなければならないことに注意.出力メモリも割り当てられ,計算が行われ,結果が可視化される.
| Out[33]= |  |
メモリ
CUDAMemoryはカーネルとそれがロードされているデバイスの両方に結び付けられているため,ワーカーカーネルには分配できない.
マスターカーネルにメモリをロードする.
| Out[34]= |  |
それから定義を分配する.
| Out[35]= |  |
分配されたCUDAMemoryはワーカーカーネルによって操作することはできない.
メモリはParallelEvaluateを使ってワーカーカーネルにロードできる.
| Out[37]= |  |
ParallelEvaluateを使ってメモリ上でさらに処理を行う.
| Out[38]= |  |
帯域幅
場合によっては,データの転送に費やす時間が計算に必要な時間より多くなることがある.
大きなリストをロードする.
並列処理では大きなリストをワーカーカーネルと共有しなければならないので,直列処理を行う場合より大幅に時間がかかる.
| Out[40]= |  |
データを転送する必要がない直列処理の方が速い.
| Out[41]= |  |