2


 単純な OpenCL カーネルを作成しているときに、セマフォを使用しようとしたところ、GPU ドライバー (AMD 12.10) がクラッシュしました。私が見つけた例をチェックした後、そのクラッシュはローカル作業サイズが 1 に等しくない場合にのみ発生します。このコードはから取得されます:

    #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
    #pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
    #pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
    #pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable

    void GetSemaphor(__global int * semaphor)
    {
      int occupied = atom_xchg(semaphor, 1);
      while(occupied > 0)
      {
          occupied = atom_xchg(semaphor, 1);
      }
    }

    void ReleaseSemaphor(__global int * semaphor)
    {
       int prevVal = atom_xchg(semaphor, 0);
    }

    __kernel void kernelNoAtomInc(__global int * num,
                __global int * semaphor)
    {
      int i = get_global_id(0);
      GetSemaphor(&semaphor[0]);
      {
        num[0]++;
      }
      ReleaseSemaphor(&semaphor[0]);
    }

著者が使用する例では

CQ.Execute(kernelNoAtomInc, null, new long[1] { N }, new long[1] { 1 }, null);

ここで、N = global_work_size および local_work_size = 1
ここで、1 を null または 2 または 4 またはその他の数値に変更すると、AMD ドライバーがクラッシュします。

CQ.Execute(kernelNoAtomInc, null, new long[1] { N }, new long[1] { 2 }, null);

現時点でテストする他の PC はありません。しかし、作者が意図的に local_group_size = 1 のままにしたのは奇妙に思えます。誰かが私にこれを説明してもらえますか? また、私が理解している限り、local_group_size を 1 のままにすると、パフォーマンスに大きな影響がありますか? ありがとう。

ホスト: Win8 x64、HD6870

4

1 に答える 1

1

あなたの問題は再現性がなく、リンクからソースを見つけることもできませんが、クラッシュする可能性がある理由についていくつかのアイデアがあります (9 年前)。

おそらくクラッシュします。なぜなら...

  • ...ドライバーはatom_xchg()、代わりにグローバルバージョンが必要な場合に、その関数のローカルバージョンを実行したいと考えています。
  • ...あなたのループは、古いマシンでそのカーネルの実行を大幅に遅くし、実行時間の内部制限を超えて、ドライバーがカーネルを終了させました。

可能な修正のために私が提案できること:

  • カーネルで atom 関数のローカル バージョンをアクティブにしないでください。
  • CPUで動かしてみる

あなたのコンピューターにアクセスしてデバッグできない限り、これを修正する方法はありません。


また、作成者が local_group_size を 1 つ選択した理由も尋ねていました。これは、割り算が自然数になるように、グローバル ワーク サイズがローカル ワーク サイズで割り切れる必要があるためです。自然数を 1 で割ると必ず自然数になるので、実験に最適です。それがパフォーマンスに大きく影響すると言って、あなたは完全に正しいです。(計算が合わず、クラッシュもしなかったのかもしれませんが、起動さえしませんでした)


別のメモ:

  • インクリメントを機能的に正しくするには、バッファで を使用する必要がありatom_inc()ますnum。これがどのようにクラッシュにつながるかはわかりませんが、プログラムが意図したとおりに機能しないことは間違いありません
  • 2.0 標準のアトミック関数を使用します。これは、セマフォのような関数が既に備わっているためですbool atomic_flag_test_and_set(volatile atomic_flag *object)void atomic_flag_clear(volatile atomic_flag *object)
于 2022-02-09T22:08:49.443 に答える