0

CPU で OpenCL を使用して実験を行っています。カーネル内にループがあり、ローカル グループ内のすべてのスレッドが各反復の途中と各反復の最後に同期されます。私がこれを行う理由は、cl_mem オブジェクトを作成し、各反復でカーネルをキューに入れることのオーバーヘッドが、並列化の利点よりも大きいように思われるためです。

同期のために、グローバル作業サイズに等しいローカル グループ サイズをカーネルに渡しました。カーネルは、すべての CPU コアではなく、1 つの CPU コアで実行されているようです。

1 つのローカル グループを複数のコンピューティング ユニットで実行できますか? そうでない場合、複数のコンピューティングユニット間の同期を維持する方法はありますか?

4

1 に答える 1

0

実行中に異なるワーク グループを同期することはできません。

計算ユニットは通常、タスクを同期するために通信できるプロセッサのグループです。たとえば、Nvidia コンピューティング ユニット (ストリーミング マルチプロセッサ) には 8 つのストリーミング プロセッサがあり、この特定のコンピューティング ユニットで実行されているタスクを同期することしかできません。

あなたが言及したオーバーヘッドが本当にあるかどうか、私は最初に見つけようとします:

同期がどのように機能し、複数のカーネルを単純にエンキューするのにどれだけ効率的かは、使用しているシステムによって異なります。CPU は、GPU メモリなどに転送する必要がないため、多くの異なるカーネルを処理するのに非常に優れています。

ベンチマークを行うことをお勧めします。OpenCL は強力なプロファイリング機能を提供します。CL_QUEUE_PROFILING_ENABLE でキューを初期化する必要があります。その後、たとえば次のように各イベント オブジェクトのプロファイリング情報を出力できます (私は C++ バインディングを使用しています)。

std::vector<cl::Event> evts;
//[Create some event objects by enqueueing and executing kernels]
for (unsigned int i=0; i<evts.size(); i++) {
  evts[i].getProfilingInfo(CL_PROFILING_COMMAND_QUEUED, &param);
  printf("%u: %llu", i, param);
  evts[i].getProfilingInfo(CL_PROFILING_COMMAND_SUBMIT, &param);
  printf(" %llu", param);
  evts[i].getProfilingInfo(CL_PROFILING_COMMAND_START, &param);
  printf(" %llu", param);
  evts[i].getProfilingInfo(CL_PROFILING_COMMAND_END, &param);
  printf(" %llu\n", param);
}
于 2012-09-07T06:22:37.780 に答える