2017-01-24 14 views
1

同じOpenCLプログラムが異なるOpenCLデバイスでコンパイルされている可能性があります。各デバイスに対して、コマンドキューが作成されます。たとえば、CPU用とGPU用の2つのキューがあります。複数のホストスレッドから異なるOpenCLコマンドキューを使用する

2つのコマンドキューで、異なるホストスレッド(コマンドキューごとに1つ)からclEnqueueNDRangeKernel、次にclEnqueueReadBuffer(ブロッキング)を呼び出すことはできますか。

// queues_ contains command queues for different contexts, 
// each with one device on one platform (e.g. CPU and GPU) 
#pragma omp parallel for num_threads(2) schedule(dynamic) 
for(int i = 0; i < job_count; ++i) { 
    cl::CommandQueue& queue = queues_[omp_get_thread_num()]; 
    // queue is for one device on one platform 
    // euqueue kernel, and read buffer on queue 
} 

このようなループとのOpenMPを使用して、例えば

は、CPUとGPUのための2つのチャンクにジョブリストを分けることになります。 schedule(dynamic)は、スケジューリングがカーネルの実行時間に動的に適応するようにします。 ホストコードは、カーネルを待っている間に(ブロックclEnqueueReadBuffer呼び出しで)ほとんどの時間を費やします。しかし、CPUデバイスのおかげで、CPUは実際には(OpenCLで)カーネルを実行するのに忙しくなり、同時にGPU (ホストコード内で)終了します。

+2

あなたの質問には、答えははいです。 – Dithermaster

+1

私は、2つのGPUSとCPU間の負荷のバランスをとったリアルタイムの光線トレーサを作成しました。私は独自のコンテキストで各デバイスのスレッドを作成することでこれを行いました。私はこのためにpthreadを使用しました(私はその時点でOpenMPを知らなかったので)が、OpenMPも同様に動作すると仮定します。当時のNvidia GPU(OpenCL 1.1)とは別のキューを作成していなかったため、Nvidiaのフォーラムでは、それぞれのデバイスごとに独自のスレッドで異なるコンテキストを作成することを推奨しました。 –

答えて

1

コンテキストが異なる場合は、3Dアプリケーションを使用してもコンテキストは独立して動作します。実装によっては、ドライバによって2つのコンテキストを先取りまたは超スレッド化できますが、キュー内の1つのアイテムがキュー内のアイテム補完を待つようなコンテキスト間のイベントベースの同期をさらに追加できます。

同じコンテキストでは、2つのキュー間の暗黙的な同期をドライバやapisの実行者操作で行うことができます。

メモリにバインドされたカーネルにすべてのCPUコアを使用すると、ダイレクトメモリアクセスを使用しない限り、gpuとの間で十分に高速に配列のコピーを実行できません。キャッシュが大きくて速い場合は、そのようなことは必要ありません。

関連する問題