2017-01-15 16 views
2

OpenGLのスレッドの実行順序が不思議です。OpenGL計算シェーダでのスレッドの実行順序

私は、しばしばn_coresから8 ... 32のモバイルGPUを持っているとします(たとえば、ARM Mali)。つまり、彼らはNvidia(AMD)ワープ(波面)とは異なります。

私が求めていた理由は、次の理由おもちゃの例

layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in; 

shared float a[16]; 

void main() { 
    uint tid = gl_GlobalInvocationID.x; // <-- thread id 

    // set all a to 0 
    if (tid < 16) { 
     a[tid] = 0; 
    } 
    barrier(); 
    memoryBarrierShared(); 

    a[tid % 16] += 1; 

    barrier(); 
    memoryBarrierShared(); 

    float b = 0; 
    b = REDUCE(a); // <-- reduction of a array a 
} 

  • であるいくつかの競合状態があるかのようにbは、実行(glDispatchCompute(1, 100, 1))の実行とは異なることが起こります。

  • ワークグループ内のスレッドが本当に並行しているかどうかはわかりません(ストリーミングマルチプロセッサのワープ)。

  • また、いくつのコアがワークグループ/シェーダにマッピングされていますか?

  • あなたの考えは?おかげで

答えて

3

いくつかの競合状態が存在するかのようにbは、実行(glDispatchCompute(1, 100, 1))の実行とは異なることが起こります。 1があるためだ

:256の局所的な大きさを持つワークグループの

a[tid % 16] += 1; 

tid % 16の同じ値を持つワークグループに少なくとも2つの呼び出しがあるでしょう。したがって、これらの呼び出しは同じインデックスaを操作しようとします。

これを防ぐ障壁やその他のメカニズムがないので、これはaの要素の競合条件です。したがって、未定義の動作が発生します。

さて、あなたはatomic operationsを通じてaを操作することができます:行動を明確に定義されている

atomicAdd(a[tid % 16], 1); 

を。


私は(ストリーミングマルチプロセッサに反りなど)本当に同時いる作業グループ内のスレッド天気を確認していません。

これは無関係です。同時に実行されるかのように扱わなければなりません。

また、いくつのコアがワークグループ/シェーダにマッピングされていますか?

本質的に無関係です。これはパフォーマンスの面で重要ですが、それは主にローカルグループサイズをどのくらい大きくするかということです。しかし、あなたのコードが動作するかどうかという点では、問題ではありません。