0

OpenCL には、すべてのスレッドを停止するグローバル バリアがないため、次のコードで回避策を作成しようとしています。

void barrier(__global uint* scratch) {
  uint nThreads = get_global_size(0);
  atom_inc(scratch);
  /* this loop never terminates */
  while(scratch[0] < nThreads) {
    continue;
  }
}

アイデアは、すべてのスレッドがその 1 つのメモリをインクリメントするまで、各スレッドがループするというものです。

ただし、scratch[0] から読み取られた値は、一度読み取られるとスレッドで変更されることはなく、永久にループします。ホストに読み戻したときに正しい値であるため、インクリメントされていることがわかります。

グローバル メモリはローカルにキャッシュされていますか? 何が起きてる?

4

1 に答える 1

0

問題が見つかりました: ワークグループが実行される順序は実装定義です。これは、一部のスレッドが他のスレッドの終了後にのみ開始される可能性があることを意味します。

私が提供したコードでは、最初に開始されたワーク グループが永遠にループし、他のグループが「障壁」にぶつかるのを待ちます。そして、後で開始される作業グループは、最初の作業グループが終了するのを待っているため、決して開始されません。

実装 (私は Radeon 5750 を使用しており、Stream SDK 2.2 を使用しています) がすべてのワーク グループを同時に実行する場合、おそらく問題にはなりません。しかし、それは私のセットアップには当てはまりません。

于 2010-09-30T18:34:22.650 に答える