2011-12-22 32 views
2

GPUでのCUDAまたはOpenCLコードの並列性に関する一般的な質問があります。私はNVIDIA GTX 470を使用しています。GPUでの並列処理 - CUDA/OpenCL

私はCudaプログラミングガイドで簡単に読んでいますが、ここではそれに関連する回答は見つかりませんでした。

私はCUDAカーネルを呼び出すトップレベルの関数を持っています(同じカーネルのために、そのOpenCLバージョンを持っています)。このトップレベル関数自体は、3つの異なるデータセット(画像データR、G、B) に対して、メイン関数から 'forループ'で3回呼び出され、実際のコードレットも画像/フレームには2 'for loops'があります。

私が知りたいことは、ここでどのような並列性が悪用されているかです。タスクレベルの並列処理またはデータ並列処理です。

このCUDAとCコードは、コードレットと最上位レベルのコードでさまざまな機能/機能用に複数のスレッドを作成し、 並列で実行し、タスクの並列処理を利用します。はいの場合、コードに明示的に含まれているかスレッドにリンクされているスレッドライブラリがないため、誰が作成しますか。

OR

それは独立したので、データの並列処理を実現しているの反復「forループ」異なるためスレッド/タスクを作成します。 この種の並列処理を行う場合、異なるforループ反復が依存関係を持たず、したがって並列にスケジューリングできることに注意してこれを利用しますか?

コンパイラ/スケジューラにループ/関数を並列にスケジュールするように指示する特別なコンパイラ構文/組み込み関数(openMPのような並列のforループ)は表示されないので、

読書資料は役に立ちます。

答えて

4

GPUでの並列処理は、SIMT(Single Instruction Multiple Threads)です。 CUDAカーネルでは、すべてのブロックにN個のスレッドがあるブロックのグリッドを指定します。 CUDAライブラリはすべてのトリックを行い、CUDAコンパイラ(nvcc)はGPUコードを生成し、GPUによって実行されます。 CUDAライブラリは、GPUドライバと、GPUのスレッドスケジューラに、カーネルを実行するスレッドの数((ブロック数)x(スレッド数))を通知します。あなたの例では、トップレベル関数(またはホスト関数)は、非同期でemediatlyを返すカーネル呼び出しのみを実行します。 nvccがドライバへの呼び出しを作成するため、スレッドライブラリは不要です。

サンプルカーネル呼び出しは次のようになります。

helloworld<<<BLOCKS, THREADS>>>(/* maybe some parameters */); 

OpenCLのは、同じパラダイムに従いますが、(彼らはプリコンパイルされていない場合)、実行時にヨールカーネルをコンパイル。カーネルを実行するスレッドの数を指定し、残りの部分はlibが行います。

CUDA(OpenCL)を学ぶ最も良い方法は、CUDA Programming GuideOpenCL Programming Guide)を見て、GPU Computing SDKのサンプルを見てください。

2

私が知りたいことは、ここでどのような並列性が悪用されているかです。タスクレベルの並列性またはデータ並列性ですか?

主にデータの並列処理ですが、タスクの並列処理も含まれています。

画像処理の例では、カーネルが1つの出力ピクセルの処理を行う場合があります。 OpenCLまたはCUDAに、出力イメージのピクセル数と同じ数のスレッドを実行するように指示します。次に、これらのスレッドが、対象とするGPU/CPU上で実行されるようにスケジュールを設定します。

高度に並列化されたデータ。カーネルは1つの作業項目を実行するように書かれており、数百万ものスケジュールを設定しています。

タスクの並列処理は、GPUがすべてのスレッドを実行している間にホストプログラムがCPU上で実行されているために発生します。しばしば、次のカーネルスレッドのセットのデータを準備していますが、完全に別個のタスクになる可能性があります。

2

複数のカーネルを起動すると、自動的には並列化されません(GPUタスクの並列処理なし)。ただし、カーネルの起動はホスト側では非同期であるため、カーネルの実行中にホストコードが並行して実行され続けます。

タスクの並列性を得るには、手作業で行う必要があります.CudaのコンセプトはストリームとOpenCLコマンドキューです。明示的に複数のストリーム/キューを作成し、各カーネルを独自のキューにスケジューリングしなければ、それらは順番に実行されます(キューが順不同で実行できるOpenCL機能がありますが、実装がサポートしているかどうかはわかりません)。 )しかし、並列にカーネルを動かすことは、各データセットがすべてのGPUコアを利用するのに十分な大きさであれば、おそらく大きなメリットはありません。

カーネルに実際のforループがある場合、それ自体は並列化されません。並列性はグリッドサイズを指定することによってもたらされ、カーネルがそのグリッドの各要素に対して並列に呼び出されますあなたのカーネルの中にforループがある場合は、各スレッドによって完全にで実行されます。言い換えれば、カーネルを呼び出すときにグリッドサイズを指定し、カーネル内でthreadIdx/blockIdx(Cuda)またはgetGlobalId()(OpenCL)を使用して、特定のスレッドで処理するデータ項目を特定します。

OpenCLを学ぶのに役立つ本はOpenCL Programming Guideですが、OpenCL specも見てみる価値があります。

関連する問題