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

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

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

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


person morteza khosravi    schedule 05.08.2017    source источник


Ответы (1)


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

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

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

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

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

person morteza khosravi    schedule 05.08.2017