2016-06-14 14 views
0

計算シェーダはタスクをどのように分割しますか?この例ではタスクは計算シェーダとどのように分割されますか?

#version 430 core 
layout (local_size_x = 64) in; 


layout(std430, binding=4) buffer INFO 
{ 
     vec2 info[]; 
}; 


void main() 
{ 

    uint gid = gl_GlobalInvocationID.x; 
    info[gid].x += 1.0; 
    info[gid].y += 1.0; 
    memoryBarrier(); 
} 

、local_size_x = 64を指定することで、それは、各作業グループが自動的に64個のスレッドを持っていることを意味し、入力がVEC2配列であるため、それだけで上の各VEC2でメインを通過することを知っています別のスレッド?

また、シェーダがvec2の入力ごとに10個のvec2を生成していて、それから別々のスレッドでそれぞれ別の何かを実行したいと思ったらどうしますか?最初の64スレッドは640に分岐します。これは同じシェーダで実行できますか、2番目のシェーダを作成する必要がありますか? local_size_x = 64を指定することによって、この例では

答えて

0

、それが各作業グループが自動的に64のスレッドを持つことになり、入力がVEC2配列であることから、それだけで、各VEC2でメインを通過することを知っていることを意味してい別スレッド?

はい、それはinvocations within a work group are definedです。

別のスレッドでそれぞれ、シェーダはすべてのVEC2入力用の10 VEC2を生成することであったと、私はそれらのそれぞれに異なる何かをしたい場合も、私は何をするでしょう。

どのようにすればそれはあなた次第です。しかし、はい、それは別のシェーダでなければなりません。計算シェーダはの呼び出しを呼び出しで作成できません。直接ではありません。

ワークグループ内に作業項目を入れる目的は、それらのローカル呼び出しが互いに通信し、何かを計算するのを助けることです。 shared variables or barrier callsがない場合は、ローカルサイズが何であるかは問題ではありません(機能の観点からではなく、ローカルサイズがパフォーマンスに影響する可能性があります)。

このように、特定のディスパッチ操作で押さえようとする作業量に基づいてローカルサイズを選択する必要があります。今では、vec2を64の整数倍で処理する必要があります。同じグループの呼び出しが同じ値を読み取っている場合は、フルグループがどのくらいの作業を行うかを再評価する必要があります。

ワークグループ内の呼び出し数の制限は、ハードウェアに依存しますが、1024以上になります。したがって、遊ぶ余地があります。

あなたの新しいシステムでは、まだ64個の入力を処理する作業グループ呼び出しが必要な場合は、明らかに作業グループのローカルサイズは640でなければなりません。サイズは合計で80.

どのようなサイズを選択しても、実際にこれを指定する最も良い方法は、ローカルサイズに複数のディメンションがあるという事実を使用することです。 X次元は入力インデックスを参照する必要があり、Y次元はXの入力からの出力インデックスです。したがって、Yサイズは10、Xサイズは8または64、または任意のものになります。あなたの入力を取得するために行くとき

したがって、あなたが必要とするインデックスは次のとおりです。

const uvec3 size_mult = {1, gl_NumWorkGroups.x, gl_NumWorkGroups.x * gl_NumWorkGroups.y}; 
const uint input_index = gl_WorkGroupSize.x * dot(gl_WorkGroupID, size_mult) + gl_LocalInvocationID.x; 

出力のためのインデックスは次のようになります。

const uint output_index = gl_WorkGroupSize.y * input_index + gl_LocalInvocationID.y; 
関連する問題