4

The SPIR-V specification allows a module to request that a branch will be flattened or a loop unrolled using control decorations for the appropriate instructions. This has a significant impact on the final performance profile of the shader. However, standard GLSL, unlike HLSL, doesn't have a way to express this. The intent is that the driver can make those decisions for you, though arguably only the developer can have enough information to do so.

Is there a way to specify how a control operation should be compiled from GLSL when using glslang, or is this left up to the driver to make these decisions? Do we still have to manually unroll loops to be sure they won't branch?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Quinchilion
  • 912
  • 6
  • 16
  • You can check the output with `glslangValidator -H`. I do hope the compiler to some degree does unroll loops with constexpr parameters. – krOoze Aug 24 '16 at 16:17
  • @krOoze: "*I do hope the compiler to some degree does unroll loops with constexpr parameters.*" It shouldn't. Because the internal SPIR-V compiler is going to have to make its own decisions about unrolling loops and such. There's no point in having the validator compiler doing that when the code that best knows how to do it will handle it. – Nicol Bolas Aug 24 '16 at 16:19
  • @NicolBolas It is a "strong" hint. What's the point then of having it, if the "external" compiler wouldn't use it... – krOoze Aug 24 '16 at 16:30
  • @krOoze: "*What's the point then of having it, if the "external" compiler wouldn't use it...*" The hint is in SPIR-V. Therefore, SPIR-V is not expected to have *already* unrolled the list. The hint is a way for the writer of the SPIR-V to communicate the desire for the compiler *accepting* SPIR-V to unroll it. It's not a directive to say that a loop has been unrolled. – Nicol Bolas Aug 24 '16 at 16:53
  • @NicolBolas of course not, that's nonsense. I mean why wouldn't it decorate. (or split the loop and then decorate, to partially unroll). – krOoze Aug 24 '16 at 17:21
  • @krOoze: Based on what? GLSL has no syntax for saying whether a loop should be unrolled or not. Thus, the only way that the compiler could apply that decoration is by using some heuristic. A heuristic that *cannot* be based on the destination hardware, and therefore a heuristic that could produce slower shaders. – Nicol Bolas Aug 24 '16 at 17:31

1 Answers1

3

Is there a way to specify how a control operation should be compiled from GLSL when using glslang

There is no explicit means in GLSL to request such things. There may be glslangValidator switches that can control it, but even then, that would be a global setting, not a per-loop setting.

Do we still have to manually unroll loops to be sure they won't branch?

That's the only way to "be sure they won't branch". Even with SPIR-V's unroll decoration, that is a request, not a guarantee. If the internal SPIR-V compiler doesn't want to unroll that loop, then it won't, regardless of what you tell it.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • In the specification, the flag is worded as _"Strong request, to the extent possible, to unroll or unwind this loop."_ Is it wrong to assume that such a loop will be unrolled, as long as it is at all possible (number of iterations known at compile time)? – Quinchilion Aug 24 '16 at 16:30
  • 1
    @Quinchilion You read the same text as we do... Define possible. Is unrolling to 1 GB of commands "possible"? – krOoze Aug 24 '16 at 16:32
  • @krOoze What I meant by that remark is that if I understand the specification correctly, then yes, I can be (very reasonably) sure such a decorated loop won't branch. – Quinchilion Aug 24 '16 at 16:39
  • @Quinchilion: It all depends on how you define "(very reasonably) sure". It's still a *hint*, and compilers are given the right not to fulfill it if they so desire, for whatever reason they so desire. This does not mean that it is useless. However, remember the fate of the buffer object hints in OpenGL. They were so poorly used by people that several implementations *ignored them*, instead using heuristics to decide where buffers were stored. If people misuse the unrolling hint, thus causing shaders to execute more slowly, I imagine Vulkan implementations will start disregarding it. – Nicol Bolas Aug 24 '16 at 17:01
  • @NicolBolas Fair point. I fear some implementations might start to ignore them not because people will misuse the hints, but because they won't use them at all, given that there is no good way to do so with the official glsl compiler. It seems strange to me that despite the "explicitness" of Vulkan, there hasn't been given much desire to provide an explicit shader interface as well. – Quinchilion Aug 24 '16 at 17:20
  • @Quinchilion maybe there is... It's Vulkan v1, it does not have decades of evolution behind it. Nevertheless people expect all the things all at once. I mean it does not expose Int8 and half-float neither which the SPIR-V has. At least you probably can use the hints by somehow authoring SPIR-V directly. Also there is the matter of staying +- compatible with classic GLSL and HLSL and others. – krOoze Aug 24 '16 at 17:27
  • 1
    @Quinchilion: But there is an "explicit shader interface" for Vulkan: SPIR-V. What there isn't is a higher-level language that exposes all that SPIR-V provides. – Nicol Bolas Aug 24 '16 at 17:33