【问题标题】:GLSL branching behaviourGLSL 分支行为
【发布时间】:2010-11-28 22:30:45
【问题描述】:

我有一个带有分支的相当简单的片段着色器,我有点不确定 GLSL 编译器如何处理它以及它会如何影响性能。

uniform sampler2D sampler;
uniform vec2 texSize;
uniform vec2 targetSize; 

void main()               
{                  
    vec4 color;
    if(texSize == targetSize)
        color = texture2DNearest(sampler, gl_TexCoord[0]);
    else
        color = texture2DBicubic(sampler, gl_TexCoord[0]);
    gl_FragColor = color;        
}

我从AMDs document 中读到,有时会执行两个分支,在这种情况下这不是一个好主意。没有更多信息也没有反汇编权限,我不确定该怎么想,如果这是一个问题,如何避免?

据我了解,基于统一变量的分支不会产生任何重大开销,因为它在单次传递中是恒定的?

【问题讨论】:

    标签: opengl glsl


    【解决方案1】:

    给你:

    il_ps_2_0
    dcl_input_generic_interp(linear) v1
    dcl_resource_id(0)_type(2d)_fmtx(float)_fmty(float)_fmtz(float)_fmtw(float)
    eq r2.xy__, c1.xyyy, c0.xyyy
    imul r5.x___, r2.x, r2.y
    mov r1.x___, r5.x
    if_logicalnz r1.x
        sample_resource(0)_sampler(0) r6, v1.xyyy
        mov r7, r6
    else
        sample_resource(0)_sampler(0) r8, v1.xyyy
        mov r7, r8
    endif
    mov r9, r7
    mov oC0, r9
    endmain
    

    改写一下 Kos 所说的,重要的是在执行之前知道是否可以知道保护条件。这里就是这种情况,因为c1c0 寄存器是常量(常量寄存器以字母'c' 开头),r1.x 寄存器值也是如此。

    这意味着这个值对于所有调用的片段着色器都是相同的,因此不会发生线程分歧。

    顺便说一句,我正在使用AMD GPU ShaderAnalyser 将 GLSL 转换为 IL。 您还可以为特定的一代(从 HD29xx 到 HD58xx)生成原生 GPU 汇编代码。这真是一个好工具!

    【讨论】:

    • 链接失效
    【解决方案2】:

    是的,IIRC 您不会遇到性能开销,因为单个 GPU 处理器上的单个批处理(warp)中的所有线程都将通过单个分支。 “线程”是指“着色器的单个执行行”。

    当给定处理器在给定时间执行的部分线程时会出现效率问题(AFAIK 最多可能有 32 个线程;取决于硬件,我给出的是 G80 架构的数字) 会分支成多个分支——一个处理器不能同时执行两条不同的指令,因此首先“if”分支将由一部分线程执行(其余的将等待),然后“ else" 分支将被其余分支执行。

    你的代码不是这样的,所以我相信你是安全的。

    【讨论】:

      猜你喜欢
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多