技術メモ

後で同じ状況が起こった時に思い出せるように技術的なちょっとしたことをメモする。ベストな解ではない。



Alea GPUライブラリを使ってC#で簡単GPU並列プログラミング


C#でCUDAを使ったGPUの並列処理の日本語の情報が少なかったので、C#で使えるGPUライブラリであるAlea GPUライブラリの導入方法をここに残す。
ここでは、Visual Studio (Visual C#)がインストールされていて、cudaに対応したGPUが搭載されており、cudaドライバなどがインストールされている状態のWindowsを前提としている。
これらの環境が整っていない場合はまずは整える必要がある。
この記事ではWindows 10, Visual Studio 2017 Communityを使用した場合を紹介するが他のバージョンでもそう変わらないはずである。





 

プロジェクトの作成

まずはプロジェクトを作成する。
プロジェクトの作成には特別な操作は必要なく、普通に作るだけだが、一応スクショを使って説明する。
プロジェクトの作成はVisual Studioの 「ファイル > 新規作成 > プロジェクト」を選択して新しいプロジェクトウィンドウを開く。

「Visual C# -> コンソールアプリ(.Net Framework)」を選択し、好きな名前と保存場所を指定する。(説明では名前をgpu_sample, 場所をDドライブ直下にした)
プロジェクトを作成するとProgram.csなどが自動的に生成される。





 

Alea GPUライブラリのインストール

次にAleaライブラリを使えるようにする。
ソリューションエクスプローラーのプロジェクト名のところ(この記事の通りにやっていればgpu_sample)を右クリックし、「NuGet パッケージの管理」を選択。

「NuGet: プロジェクト名」のタブが開く。参照タブが開かれていない場合は、「参照」をクリックして参照タブに移る。

検索ボックスに「alea」と打って検索をする。
出てきた「Alea」パッケージを選択し、「インストール」を押す。

なんか聞かれるので「OK」、「同意する」を選択してインストールする。


Aleaのインストールが終わったら同様の方法で「FSharp.Core」もインストールする。(Aleaを動かすのに必須)
検索ボックスに「fsharp」などと入力することで検索に引っかかる。
検索に引っかかった「FSharp.Core」を選択し、「インストール」を押す。

また、同意するかどうか聞かれるので同意してインストールする。

以上でAlea GPUライブラリを使う準備ができた。





 

Alea GPUライブラリを使ってGPU並列処理をする

ソースファイル(Program.csなど)のusingディレクティブにusing Alea;using Alea.Parallel;を追加する。
Gpuインスタンスの取得はGpu.Defaultで可能である。
並列処理を行うにはGpuクラスのForメソッド(void Gpu.For(int from,int to,Action op))を用いる。
これによって(to-from)回繰り返しが行われ、Actionにはループカウンタの変数が渡される。
例えば、0~99までの数字をコンソールに出力するプログラムは普通に書くとfor(int i=0;i<100;i++){Console.WriteLine(i);}であるが、並列処理で書くとGpu.Default.For(0,100,i=>{Console.WriteLine(i);});となる。for文を使った場合は逐次処理されるので0から順番に99まで表示されるが、並列処理の場合は並列に実行されるので0から順番に表示される保証はない。

0~99までの数字をスペースで区切って表示するプログラムの例を示す。

[実行結果]

完了!
96 97 98 99 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

上記のコードだと実行結果を見ればわかるように、出力する順番がバラバラなのに加えて、「完了!」の文字が最初に来てしまっている。
「完了!」を最後に出す場合は同期をする必要がある。同期はしたいタイミングでvoid Gpu.Syncronize()メソッドを用いる。

つまり、下記のようにコードを書けば0~99までの数字を出力し終わったタイミングで同期され、「完了!」が一番最後に表示される。

[実行結果]
96 97 98 99 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
完了!




 

Alea GPUライブラリは簡単に使用でき、上手く使いこなせば実行速度の高速化が可能になる。
ぜひGPUが使えるPCで重い非同期処理をしたい時に使うと良い。





 


タグ: ,
投稿日: 2017年11月20日
最終更新日:





コメントを残す

回答をお約束することは出来ませんので予めご了承ください。
コメントは承認されると表示されるようになります。
コメントを送信する前に「私はロボットではありません」にチェックを入れて下さい。