0

カーネルのアトミック操作について詳しく調べてみると、奇妙なことがわかりました。私が理解しているように、アトミック操作が1つの番号で使用されると、すべてのスレッドからのこの種の操作はすべてシリアル化され、整合性を維持するためにこの番号で起動されます。以下は私のカーネルコードの一部です:

    if(atomic_cmpxchg(&A[ptr],0,-1) == -1)
        ptr = A[ptr + 3];

    //To delay
    uint k = 1000000;
    while(k--);

    A[ptr + 3] = newValue;

上記のコードでは、T1 と T2 の 2 つのスレッドしかないとします。私が理解しているように、T1 と T2 は両方ともコード スニペットを実行しますが、atomic_cmpxchg 操作を実行しようとすると、T2 は T1 が終了するまで待機する必要があります (T1 が最初に実行されたとします)。私が設計したように、T1 が A[ptr] を読み取ると、A[ptr] の古い値は 0 であるため、アトミックに -1 に変更されます。その後、T1については条件が満たされていないため、T1はそのままディレイコードに行き遅延します。ここで、T2 が A[ptr] を操作するときが来ました。これは、A[ptr] が -1 に設定されているため、T2 の条件が満たされているため、T2 は「ptr= A[ptr + 3];」に実行されます。 . しかし、私の問題は、T2が条件判定を終了した後、「ptr = A [ptr + 3];」を実行するためです。すぐに、しかし T1 は遅延に遭遇し、そのため、A[ptr+3] の値は T1 によってまだ更新されていません (k が非常に大きく、遅延が非常に長くなるため)。そのため、T2 は A[ptr+3] の最新の値を読み取らず、newValueしかし、私の実験では、 k値をどれだけ大きく設定しても、結果は常に正しいことが示されています。つまり、 T1 のレイテンシーがどれほど長くても、T2 は常に正しい値 ( newValue ) を読み取ることができます。誰でもこのケースを調べるのを手伝ってもらえますか? どうもありがとう。

4

1 に答える 1

2
  1. コンパイラはおそらく、「遅延」ループに副作用がなく、完全に最適化されていないことを理解するのに十分賢いです。

  2. GPU では、同じワーク グループの OpenCL ワークアイテムは通常、ロックステップで実行されます(正確なハードウェアに応じて、少なくともある程度まで)。これは、両方のスレッドが同じ命令を同時に実行することを意味します。それらは基本的に命令ポインタを共有します。発散制御フローの場合、各スレッドは現在アクティブであるかどうかを記憶し、アクティブである場合にのみ現在の命令を実行します。アトミック操作は引き続きシリアライズされます。

于 2012-10-04T07:38:21.087 に答える