有没有办法在没有竞争条件的情况下同时写入无人机?
Is there a way to concurrently write to a UAV without race condition?
我有一个计算着色器,可以将一些流体模拟为粒子。从缓冲区读取粒子。每个粒子都在一个线程中处理。在线程执行期间,一个粒子移动其 uv 位置并添加到名为 Water 的无人机的像素中。因此,每个线程都会在 Water 纹理上留下其运动轨迹。
_watTx[texID] += watAddition * cellArea.x;
问题是有很多粒子四处移动,而且大多数情况下多个粒子同时出现 texID
。似乎存在竞争条件,因为每次我 运行 模拟结果都略有不同。有没有办法强制互斥,这样写入就不会同时发生并且结果变得可预测?
我找到了解决这个问题的方法。 InterlockedAdd 以原子方式添加到像素。但它只适用于 int
和 unit
无人机。
在我的例子中,值是浮点数,但范围非常有限(比如 0 到 10)。所以解决方案是使用 int
无人机。我们将计算结果乘以一个巨大的数字(比如10000),然后写入无人机:
InterlockedAdd(_watTx[texID], (watAddition * cellArea.x * 10000));
结果的精度为 0.0001,这对我来说非常好。在此之后,在另一个像素或计算着色器中,我们可以将来自 int UAV 的值乘以 0.0001 并写入所需的浮点渲染目标。
此过程消除了并发写入问题,每个 运行 的结果都相同。
我有一个计算着色器,可以将一些流体模拟为粒子。从缓冲区读取粒子。每个粒子都在一个线程中处理。在线程执行期间,一个粒子移动其 uv 位置并添加到名为 Water 的无人机的像素中。因此,每个线程都会在 Water 纹理上留下其运动轨迹。
_watTx[texID] += watAddition * cellArea.x;
问题是有很多粒子四处移动,而且大多数情况下多个粒子同时出现 texID
。似乎存在竞争条件,因为每次我 运行 模拟结果都略有不同。有没有办法强制互斥,这样写入就不会同时发生并且结果变得可预测?
我找到了解决这个问题的方法。 InterlockedAdd 以原子方式添加到像素。但它只适用于 int
和 unit
无人机。
在我的例子中,值是浮点数,但范围非常有限(比如 0 到 10)。所以解决方案是使用 int
无人机。我们将计算结果乘以一个巨大的数字(比如10000),然后写入无人机:
InterlockedAdd(_watTx[texID], (watAddition * cellArea.x * 10000));
结果的精度为 0.0001,这对我来说非常好。在此之后,在另一个像素或计算着色器中,我们可以将来自 int UAV 的值乘以 0.0001 并写入所需的浮点渲染目标。
此过程消除了并发写入问题,每个 运行 的结果都相同。