マルチコア プロセッサと GPU を搭載したコンピュータを使用しているとします。プラットフォームのすべてのコアで実行される OpenCL プログラムを作成したいと考えています。これは可能ですか、それともカーネルを実行する単一のデバイスを選択する必要がありますか?
4 に答える
いいえ、CPUとGPUの両方でカーネルを自動的にスパンすることはできません。どちらか一方です。
それは可能ですが、これには2つのコマンドキュー(デバイスごとに1つ)を手動で作成および管理することが含まれます。
このスレッドを参照してください: http ://devforums.amd.com/devforum/messageview.cfm?catid = 390&threadid = 124591&messid = 1072238&parentid = 0&FTVAR_FORUMVIEWTMP = Single
理論的には可能です。CL API で許可されています。しかし、プラットフォーム/実装はそれをサポートする必要があり、ほとんどの CL 実装がサポートしているとは思いません。
これを行うには、CPU デバイスと GPU デバイスの cl_device_id を取得し、clCreateContext を使用してこれら 2 つのデバイスのコンテキストを作成します。
1 つのコンテキストは、1 つのプラットフォームに対してのみ使用できます。マルチデバイス コードが複数のプラットフォーム (Intel プラットフォーム CPU OpenCL、NVidia GPU など) で動作する必要がある場合は、個別のコンテキストが必要です。
ただし、GPU と CPU がたまたま同じプラットフォームにある場合は、1 つのコンテキストを使用できます。
同じプラットフォーム (2 つの同一の GPU、または同じメーカーの 2 つの GPU) で複数のデバイスを使用している場合は、両方が単一の clGetDeviceIDs 呼び出しから取得されている限り、コンテキストを共有できます。
編集: GPU+CPU コンテキストは、自動的に管理される CPU+GPU の実行を意味するものではないことを追加する必要があります。通常、パフォーマンスを最大化するために、GPU が DMA できるメモリ バッファーをドライバーに割り当てさせるのがベスト プラクティスです。CPU と GPU が同じコンテキストにある場合、これらのバッファーを 2 つのデバイス間で共有できます。
ワークロードを自分で分割する必要があります。私のお気に入りの負荷分散手法は、イベントを使用することです。n 個の作業項目ごとに、イベント オブジェクトをコマンドにアタッチ (またはマーカーをエンキュー) し、n 個の作業項目の前に設定したイベント (前のイベント) を待ちます。待つ必要がなかった場合は、そのデバイスで n を増やす必要があります。待つ必要があった場合は、n を減らす必要があります。これにより、キューの深さが制限されます。n は、デバイスをビジー状態に保つために最適な深さでホバリングします。GUI レンダリング スタベーションの原因とならないように、とにかくそれを行う必要があります。n 個のコマンドを各コマンド キュー (CPU と GPU に別々の n がある) に保持するだけで、完全に分割されます。
You cannot span a kernel to multiple devices. But if the code you a re running is not dependant on other results (ie: Procesing blocks of 16kB of data, that needs huge processing), you can launch the same kernel on GPU and CPU. And put some blocks on the GPU and some on the CPU.
That way it should boost up the performance.
You can do that, creating a clContext shared for CPU and GPU, and 2 command queues.
This is not aplicable to all the kernels. Some times the kernel code applies to all the input data, and is not able to be separated in parts or chunks.