【发布时间】:2018-02-07 06:22:56
【问题描述】:
问题
barrier() 的使用是否允许遵循但在发散流控制之外?
详情
在符合 OpenGL 4.00 的计算着色器中,我正在做一些涉及发散(即非动态统一)分支语句的工作。稍后在同一个着色器中,我需要同步该工作组内所有调用的执行,以实现内存访问。这也有利于提高效率,因为我希望它们彼此同步。但是,在咨询了 khronos.org wiki 和 refpages 之后,我不清楚我想做的事情是否符合标准(无论它在实践中是否有效)。
从this page,我们看到:
对barrier的调用不得放在任何控制流中。
从this page,我们看到:
barrier()可以从流控中调用,但只能从统一流控中调用。导致对barrier()求值的所有表达式必须是动态统一的。
首先,关于流量控制的明显矛盾。我假设只有发散的(在工作组内)流控制是不允许的?
其次,在我看来,关于在发散流控制之后 调用barrier() 时出现了一些歧义。重要的是,再次注意“所有导致对barrier()求值的表达式必须是动态统一的”的断言。这是否意味着导致,或...?一些例子可以帮助说明我的困惑。
示例1,有效:
void main() {
// ... do some work here ...
barrier(); // valid use case
// ... do some more work ...
}
示例2,有效:
void main() {
if (IS_BEST_WORK_GROUP) { // dynamically uniform within work group
// ... do some work here ...
barrier(); // valid use case
// ... do some more work ...
}
}
示例3,无效:
void main() {
if (IS_BEST_INVOCATION) { // divergent within work group
// ... do some work here ...
barrier(); // this is illegal
// ... do some more work ...
}
}
示例 4,模棱两可:
void main() {
if (IS_BEST_INVOCATION) { // divergent within work group
// ... do some work here ...
}
barrier(); // is this allowed?
// it occurs after, but outside of, a divergent branch statement
// ... do some more work ...
}
- 如果示例 4 确实有效,我会在哪里以明确的形式找到此信息?
- 或者,如果它无效,是否有其他机制可用于让我的所有调用在分歧分支条件后重新进入锁步?
- 如果以上两项都不是,这是否可以在 Vulkan 中完成?
【问题讨论】: