Есть ли способ одновременно написать на БПЛА без условий гонки?
У меня есть компьютерный шейдер, который имитирует некоторую жидкость как частицу. Частицы читаются из буфера. Каждая частица обрабатывается в одном потоке. Во время выполнения потока одна частица перемещает свое ультрафиолетовое положение и добавляет к пикселю БПЛА с именем 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 и записать в желаемую цель рендеринга с плавающей запятой.
Этот процесс устраняет проблему одновременной записи, и результаты идентичны при каждом запуске.