met*_*eap 1 opengl parallel-processing gpgpu glsl fragment-shader
片段着色器使用两个原子计数器.它可能会或可能不会增加第一个,可能会或可能不会增加第二个(但从不两者).但是,在修改计数器之前,总会读取它们的当前值,如果计数器稍后被修改,那些先前读取的值将用于某些自定义逻辑.所有这些都发生在(很可能是不可滚动的)循环中.
设想一个大致如下的流程:
问题:着色器查询当前计数器值 - 它是否始终获得"最新"值?我是否在这里失去了碎片着色器的大规模并行性(仅就当代和未来的GPU和驱动程序而言)?
至于分支(如果x) -我比较另一纹素(readonly restrict uniform)uimage1D的(uniform)uint.因此,一个操作数肯定是一个统一的标量,但另一个是一个imageLoad().x虽然图像是统一的 - 这种分支仍然是"完全并行化"的吗?你可以看到两个分支都是两个,几乎相同的指令.假设一个"完美优化"的GLSL编译器,这种分支是否会引入停顿?
原子计数器是原子的.但是每个原子操作仅对该操作是原子操作.
因此,如果要确保每个着色器从计数器获取唯一值,则每个着色器必须仅使用atomicCounterIncrement(或者Decrement,但它们必须全部使用相同的一个)来访问该计数器.
做你正在建议的正确方法是:
atomicCounterIncrement(AC1),存储返回的值.atomicCounterIncrement(AC2),存储返回的值.你的"获取和后来的增量"策略是等待发生的竞争条件.它是否"完全并行化"并不重要,因为它已被破坏.在想知道它是否会很快之前,你需要它才能工作.
在尝试解决GPU问题之前,我强烈建议熟悉原子和线程上的CPU.这是初学者在处理atomics时常犯的错误.如果要成功使用GLSL原子和图像加载/存储,则需要成为线程专家(或至少是中级).