如何同步OpenGL计算着色器软体模拟的数据

of1yzvn4  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(229)

我正在尝试使用OpenGL计算着色器进行软体物理模拟。我正在使用Spring/质量模型,其中对象被建模为由Spring连接的粒子网格组成(Wikipedia link with more details)我的计划是有一个大的SSBO来存储每个粒子的位置、速度和净力。我将有一个计算着色器,对于每个Spring,计算Spring两端的粒子之间的力(使用胡克定律),并将其添加到这两个粒子的净力中。然后,我将使用另一个计算着色器,使用SSBO中的数据对每个粒子进行某种欧拉积分,然后将下一帧的净力归零。
我的问题是内存同步。每个粒子都连接到一个以上的Spring,所以在第一个计算着色器中,不同的调用将添加到内存中的同一位置Spring计算不 * 使用 * 来自该变量的数据,因此写入可以以任何顺序进行,但我不熟悉OpenGL内存的工作原理,而且我不知道如何避免竞态条件。另外,从我所读到的内容来看,我似乎需要在对spring和particle compute着色器的调用之间使用glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT),以便前者写入的数据对后者是可见的。这是必要的/足够的吗?
我不敢做实验,因为我不知道OpenGL对未定义的行为和不小心把你的计算机搞砸有什么保护。

sxpgvts3

sxpgvts31#

不同的调用将被添加到内存中的同一个位置(保存净力的位置)。Spring计算不使用该变量的数据,因此写入可以以任何顺序进行
在这种情况下,您需要在GLSL中使用atomicAdd(),以确保两个单独的线程不会进入争用状态。
对于您的情况,我认为这不会是性能问题,但您应该知道atomicAdd如果许多线程同时命中内存中的同一位置,()可能会导致速度大幅减慢(它们必须串行化并等待彼此)。这种性能问题称为“争用”,根据问题的不同,您通常可以通过使用warp-level原语来确保每个warp中只有一个线程需要实际提交atomicAdd()(或其他原子操作)来大大改进它。
此外,“翘曲”是英伟达的术语,AMD称之为“波前”,还有不同的名称仍然对其他硬件供应商和API的。
此外,从我所读到的内容来看,我似乎还需要glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)
这是正确的。从概念上讲,我认为OpenGL计算着色器默认是异步的。这意味着,当你启动一个计算着色器时,无法保证它相对于后续命令的执行时间。glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)基本上会在访问该类型资源的任何绘制/计算命令之间创建一个wait()

相关问题