10
\$\begingroup\$

With the availability of compute shaders for both DirectX and OpenGL it's now possible to implement many algorithms without going through the rasterization pipeline and instead use general purpose computing on the GPU to solve the problem.

For some algorithms this seems to become the intuitive canonical solution because they're inherently not rasterization based, and rasterization-based shaders seemed to be a workaround to harness GPU power (simple example: creating a noise texture. No quad needs to be rasterized here).

Given an algorithm that can be implemented both ways, are there general (potential) performance benefits over using compute shaders vs. going the normal route? Are there drawbacks that we should watch out for (for example, is there some kind of unusual overhead to switching from/to compute shaders at runtime)?

Are there perhaps other benefits or drawbacks to consider when choosing between the two?

\$\endgroup\$
  • \$\begingroup\$ If the performance tag is indeed relevant, then consider watching this video from Game Engine Gems "Cloth Simulation" article from Marco Fratarcangeli: youtube.com/watch?v=anNClcux4JQ. You could read the comments and find out an awkward thing: the GLSL/shader based implementation was faster than using CUDA or OpenCL (the latter because of poor driver support at the time, in 2010). There are certain low-level differences that.. make a difference. \$\endgroup\$ – teodron Oct 27 '13 at 15:51
  • \$\begingroup\$ @teodron I don't have GPU Gems available and I can't find the source code. Did the author actually use GLSL vertex + pixel shaders or did he use GLSL compute shaders? \$\endgroup\$ – TravisG Oct 27 '13 at 17:34
  • \$\begingroup\$ Yes! Before CUDA, that's how the community implemented GPGPU features. Here's a link to OpenCloth to see how one may achieve just that using pure GLSL OR Cuda: code.google.com/p/opencloth/source/browse/trunk/… \$\endgroup\$ – teodron Oct 28 '13 at 7:44
7
\$\begingroup\$

There is no right answer if you are going to directly benefit from the compute shadrs/ GPGPU appraoch, this is highly dependent on the type of algorithm you are implementing, compute shaders and CUDA/OpenCL are a more generalized approach to overcome some of the limitations of that old shading languages hack. the most important benefits you will get:

  • Accessing spatial info. in the old GLSL hack (well, it was a hack!) only gives little info about neighbor fragments since it uses texture coordinates. In compute shaders/CUDA/OpenCL accessing spatial info is much more flexible, you are now able implement algorithms like Histogram equalization on the GPU with un-ordered texture/buffer access.
  • Gives you thread synchronization and atomics.
  • Compute Space: the old GLSL hack will hard-wire the vertex/fragment compute space to your shader. Fragment shader will run with the number of fragments, vertex shader will run with the number of vertices. In compute shader you define your own space.
  • Scalability: your compute shader/CUDA/OpenCL can scale up to the number of GPU SMs ( Streaming Multiprocessor) available unlike your old GLSL shader that should be executed on the same SM. (Based on Nathan Reed comments he says that's not true, and shaders should scale up as good as compute shaders should. I am still not sure though I need to check the documentation).
  • Context switching: There should be some context switching, but I would say that depends on the application so your best bet is to profile your application.

Well in my opinion, if you want to go the compute shaders route, even though certain algorithms may be more suitable, there are certain considerations you need to take into account:

  1. Hardware and backward compatibility. Compute shaders are only available in newer hardware and if you are going for a commercial product (e.g. game) you need to expect that a lot of users may not be able to run your product.
  2. You usually need extra knowledge in GPU/CPU architecture, parallel programming and multithreading(e.g. memory sharing, memory coherency, thread synchronization, atomics and it's effect on performance) that you usually don't need using normal shaders rounte.
  3. Learning resources, from experience there are far less learning resource for Compute shadrs, OpenCL and CUDA (which also offer OpenGL interoperability) than the usual shaders route.
  4. Debugging tools, with the lack of proper debugging, tools development can become much harder than most shaders, at least shaders can be debugged visually.
  5. I expect compute shaders to give better performance than the same algorithm in other shaders; if they were done right taking into consideration things from point 2, since they were designed to avoid the extra steps for graphics rendering. But I don't have any concrete evidence to support my claim.
  6. You should also consider CUUDA/OpenCL for GPGPU if you are going that route.

Never the less I am sure it's great for the future, and will be great learning experience. Good Luck!

\$\endgroup\$
  • \$\begingroup\$ I think the OP might be asking this: why solve a problem using pure GLSL shaders vs. coding it in CUDA? There's a Game Programming Gems article concerning cloth simulation where the author does just that. And the GLSL hacky old way is better than the CUDA way in terms of performance. You probably should point out why if you have any idea why. \$\endgroup\$ – teodron Oct 27 '13 at 15:45
  • 1
    \$\begingroup\$ I don't think your scalability point is correct - vertex and fragment shaders are just as capable of scaling across the whole GPU as compute shaders are. Actually compute shaders can be more difficult to scale, as threadgroup size and shared memory usage can put additional limits on how many shader threads can be running at a time. \$\endgroup\$ – Nathan Reed Nov 5 '13 at 8:06
  • 1
    \$\begingroup\$ Also, if you're populating a texture (e.g. generating noise or doing some other procedural algorithm), in my experience a fragment shader will be faster than a compute shader if you are simply evaluating a formula at each pixel. My guess is this is because the fragment order matches the internal tiled/swizzled pixel order, thus getting better memory locality than the compute shader that is unaware of this order. Compute shaders are only faster if you can use their special features, e.g. shared memory, to speed things up a lot relative to a fragment shader. \$\endgroup\$ – Nathan Reed Nov 5 '13 at 8:11
  • 1
    \$\begingroup\$ OK, last comment. :) I think most current GPUs have some sort of context switch or mode switch when going from graphics to compute and vice versa. So if you run some graphics shaders, then dispatch a compute shader, then run some more graphics shaders etc., you're incurring some performance hit when switching back and forth. That's something you'd have to profile, but it could be another reason to stick with graphics shaders in a particular case. \$\endgroup\$ – Nathan Reed Nov 5 '13 at 8:15
  • \$\begingroup\$ @NathanReed thanks for the comments I will update my answer. \$\endgroup\$ – concept3d Nov 5 '13 at 10:48

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.