1
$\begingroup$

I am trying to learn compute shaders from source codes, but i am a bit confused by whats going on in the code so am hoping someone can help answer some questions i have.

The algorithm is the fast fourier transform butterfly algorithm. Using i beleive N = 256 for this code they have the follow setup in java, at least a poriton of the algorithm anyway:

// 1D FFT horizontal 
for (int i=0; i<log_2_N; i++)
{   
    butterflyShader.updateUniforms(pingpong, 0, i);
    glDispatchCompute(N/16,N/16,1); 
    glFinish();
    pingpong++;
    pingpong %= 2;
}

In the compute shader, a small snippet of the code has this:

complex H;
ivec2 x = ivec2(gl_GlobalInvocationID.xy); //notice this is used on imageLoad

if(pingpong == 0)
{
    vec4 data = imageLoad(twiddlesIndices, ivec2(stage, x.x)).rgba;
    vec2 p_ = imageLoad(pingpong0, ivec2(data.z, x.y)).rg;
    vec2 q_ = imageLoad(pingpong0, ivec2(data.w, x.y)).rg;
    vec2 w_ = vec2(data.x, data.y);

    complex p = complex(p_.x,p_.y);
    complex q = complex(q_.x,q_.y);
    complex w = complex(w_.x,w_.y);

    //Butterfly operation
    H = add(p,mul(w,q));

    imageStore(pingpong1, x, vec4(H.real, H.im, 0, 1));
}

So my first question is, they opted to do : glDispatchCompute(N/16,N/16,1); What is the deciding factor for picking the total threads here? They use it for a texture lookup in the compute shader, so does this mean the total number of threads must be equal to the image dimensions or it won't work, i am not familiar with gl_GlobalInvocationID.xy and how it relates to a texture lookup.

Secondly, i notice in a lot of example codes thread numbers seem to be matched eg: [8,8,1] does this mean compute shaders prefer equal x and y threads? So something like [8,4,1] is generally not a good idea and is best to just round up to [8,8,1]?

Lastly what are the important deciding factors when choosing how many threads for a piece of code? And does GlobalInvocationID.xy basically provide [0,0] to [numThreads.x-1,numThreads.y-1] based on the number the user chose?

If not i don't understand how the ID knows to provide the same amount of .xy values with the image size they are doing lookups on.

$\endgroup$
  • 2
    $\begingroup$ "I am trying to learn compute shaders from source codes" Learning complicated concepts by reading code almost never works. $\endgroup$ – Nicol Bolas Mar 18 at 13:18
  • $\begingroup$ Did you try reading the opengl wiki on Compute Shaders. The wiki does an amazing job at laying out the roadmap I'd say. khronos.org/opengl/wiki/Compute_Shader If you find yourself wanting more about the optimal numbers for workgroup etc you'll need to learn a little bit about the GPU architecture. My answer here can be useful. computergraphics.stackexchange.com/questions/8165/… $\endgroup$ – gallickgunner Mar 18 at 14:06
  • $\begingroup$ @NicolBolas Well i'm trying to transcribe this into C# so learning the entirety of shaders for that is a bit ridiculous. But even then i understand a fair deal about shaders, but this particular aspect i didn't grasp well. @gallickgunner i did read most of it but it didn't answer the questions i had. Because it doesn't state for global invocation if it by default ranges from [0,0] to [n-1.n-1] it mentions an ID not some coordinate so i don't quite get why they use x on the texture look up they don't seem to be related. If "google it" is the answer to everything, then sorry i asked. $\endgroup$ – user10332 Mar 18 at 20:25
  • 1
    $\begingroup$ Are you trying to convert shader code to C#? Because that's not going to work out. Shaders have a fundamentally different execution model. So even if you ported the code, it would likely be really inefficient because of the differences in what makes a CPU implementation fast vs. a GPU implementation. $\endgroup$ – Nicol Bolas Mar 18 at 21:48
  • $\begingroup$ Not 100% convert because i am aware of the differences. I am basically trying to understand how i can use linearly, double for loops in C# as a representation of GPU threads processing the images. I am basically doing the algorithm non parallel on CPU side since i don't have compute shader as an option. But its not clear to me what the range the invocation id is, i am under the assumption the .xy is 0 to (N/16) - 1 from that code but i do not know for sure, was hoping some one would know. $\endgroup$ – user10332 Mar 18 at 22:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.