Есть ли способ одновременно написать на БПЛА без условий гонки?

У меня есть компьютерный шейдер, который имитирует некоторую жидкость как частицу. Частицы читаются из буфера. Каждая частица обрабатывается в одном потоке. Во время выполнения потока одна частица перемещает свое ультрафиолетовое положение и добавляет к пикселю БПЛА с именем Water. Поэтому каждая нить оставляет след своего движения на текстуре воды.

_watTx[texID] += watAddition * cellArea.x;

Проблема в том, что вокруг движется много частиц, и чаще всего присутствуют кратные texID, Кажется, что есть условие гонки, так как каждый раз, когда я запускаю симуляцию, результаты немного отличаются. Есть ли способ обеспечить взаимное исключение, чтобы записи не происходили одновременно и результаты стали предсказуемыми?

1 ответ

Я нашел способ решить эту проблему. InterlockedAdd добавляет к пикселю атомарным способом. Но это работает только на int а также unit БЛА.

В моем случае значения с плавающей точкой, но диапазон довольно ограничен (например, от 0 до 10). Таким образом, решение заключается в использовании int БЛА. Мы умножаем результат вычисления на огромное число (например, 10000) и затем записываем в БПЛА:

InterlockedAdd(_watTx[texID], (watAddition * cellArea.x * 10000));

Результаты будут иметь точность 0,0001, что в моем случае вполне нормально. После этого в другом пиксельном или вычислительном шейдере мы можем умножить значения из int UAV на 0,0001 и записать в желаемую цель рендеринга с плавающей запятой.

Этот процесс устраняет проблему одновременной записи, и результаты идентичны при каждом запуске.

Другие вопросы по тегам