【问题标题】:Branch depending on uniform only分支仅取决于制服
【发布时间】:2013-12-05 04:13:45
【问题描述】:

我知道 GPU 程序中的分支(着色器、CUDA、CL、...)的行为与 CPU 程序中的分支不同(性能方面)。通常,着色器的实例被分组,并且来自同一组的实例计算相同的路径。如果在一个组中,有一个实例想要采用一条路径,而另一个实例想要采用另一条路径,则会评估两条路径,如果这种情况经常发生,这可能会降低性能。

但是如果着色器程序的所有实例采用相同的路径怎么办? IE。如果分支仅受单个布尔统一值影响怎么办?特别是与无分支相比(即在着色器程序的编译期间消除分支;在宿主程序中保留两个着色器程序对象并在需要时交换它们)。

uniform bool dosomething = false;

...
    if (dosomething) {
        expensiveStuff();
    }
...

上面我谈到了一个分支;但是如果分支甚至处于循环中怎么办?是否可以“检测到”它对于 (a) 所有着色器实例 + (b) 所有循环迭代总是采用相同的路径?

考虑像光线行进这样的东西,其中一些计算成本高昂的细节被制服触发/影响。

...
    for (float t = 0; t < 1; t += step) { 
        foo();
        if (dosomething) {
            expensiveStuff();
        }
    }
...

是否值得将代码转换成这样的东西(如果可能)?

...
    if (dosomething) {
        for (float t = 0; t < 1; t += step) { 
            foo();
            expensiveStuff();
        }
    } else {
        for (float t = 0; t < 1; t += step) { 
            foo();
        }
    }
...

我主要针对 NVIDIA 和 AMD GPU(GL 版本 >= 4.0),但我对更“通用”的答案感兴趣,即基于专业着色器编程经验,因为我没有。

【问题讨论】:

    标签: opengl glsl gpu nvidia amd-processor


    【解决方案1】:

    是否值得将代码转换成这样的东西(如果可能)?

    是的。

    虽然 GLSL 编译器可以进行类似的优化,但没有规范保证它

    【讨论】:

    • 我已经猜到规范不会对此发表任何评论。但我希望有人能说出 典型 实现的作用(即 NVIDIA、AMD)。
    • 所以我猜(现在是外部的)分支可能还没有优化出来,但它不会真的受伤吗? (我仍然想象最坏的情况是每个实例在外部分支上运行两条可能的路径。)
    • 在着色器非均匀控制流中使用分支(以及其他一些东西,如渐变)可能遇到的最坏情况。您对统一控制流感兴趣,这在这些平台上通常没有那么糟糕。但是,我会尽量避免使用分支。特别是对于您的uniform bool 案例,为特定案例(预)生成着色器可能更有效(可能通过在源代码中插入const bool=...)。保留一些这样的着色器变体并不是那么消耗资源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 2013-01-28
    • 1970-01-01
    • 2016-09-20
    • 2018-06-22
    相关资源
    最近更新 更多