Что происходит, когда AppendStructuredBuffer переполняется в вычислительном шейдере? - PullRequest
2 голосов
/ 10 июля 2019

У меня есть проект Unity, в котором я пишу в AppendStructuredBuffer<Triangle> через Append(triangle) в вычислительном шейдере.

В этом случае я знаю теоретический предел для количества треугольников, которые могут существовать, поэтому очевидный правильный подход заключается в соответствующем изменении размера буфера. Однако, как хак, я экспериментирую с выделением радикально меньших буферов, чтобы они могли более эффективно обрабатываться другими частями системы (в частности, чтение обратно в ЦП). Можно представить себе другие ситуации, в которых конкретный предел может быть неизвестен или ошибочно принят.

Очевидно, это потенциально опасно. Я уверен, что есть более надежные подходы, которые можно использовать для моей текущей системы (или в более общем плане), не жертвуя при этом производительностью, но я (особенно) не спрашиваю совета по этому поводу.

Что я хочу знать, так это то, что ожидаемое поведение программы при вызове Append() превышает возможности такого буфера. Я предполагаю, что он не определен и потенциально может повредить другие области VRAM, в некоторой степени зависящие от драйверов графического процессора / версии DirectX и т. Д. Может быть, это более формально определено, но я не смог выяснить это .

Конечно, даже если поведение определено , кажется, что он преднамеренно рискует. Тем не менее, я хотел бы знать:

  • Возможно ли обнаружить, что такой буфер заполнен в контексте функции ядра (учитывая высокую многопоточность, это, вероятно, нецелесообразно).
  • Как это повлияет на производительность, если это возможно.
  • Каковы последствия переполнения (в данном случае я специально ожидаю этого, но ошибки случаются).
  • Как все вышеперечисленное может отличаться для разных поставщиков оборудования, API и т. Д.

Возможно, это «безопасно», поскольку лишние данные будут просто потеряны в пустоте без затрат. В любом случае система может, например, периодически проверять заполненность буферов и выполнять любую дополнительную работу по дому, которая может потребоваться ... оставляя вопрос о том, насколько серьезными могут быть ошибки в настройке такой системы.

1 Ответ

0 голосов
/ 10 июля 2019

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

Согласно этой спецификации ,

5.3.10.2 Использование неупорядоченного подсчета и добавления буферов

... Счетчик за imm_atomic_alloc и imm_atomic_consume не имеет Переполнение или недостаточное зажимание, и обратная связь с шейдер относительно того, произошло ли переполнение / недополнение (перенос счетчик) . Единственное, что на самом деле выполняет счетчик - это способ генерация уникальных адресов, которые удобно связывать с БПЛА.

Далее https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#inst_IMM_ATOMIC_ALLOC

Счетчик не фиксируется, поэтому он переносится при переполнении.

Не думаю, что я ошибаюсь, интерпретируя 'обтекание' как длину буфера в этих случаях.

Итак, как я понимаю, ответ на этот вопрос заключается в том, что на Append() внутренний счетчик будет перенесен, и последующие вызовы закончатся перезаписью более ранних данных. Как это происходит, я в настоящее время рендеринг своего буфера без ссылки на такой счетчик (потому что я делаю еще один проход «треугольники», чтобы превратить их в вершины для рендеринга, что я в настоящее время делаю на non-AppendBuffer). Я должен поэкспериментировать с передачей буфера со счетчиком для этого вызова отрисовки, который должен позволить мне проверить, исчезает ли большая часть моей модели внезапно, когда я переполняюсь.

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

...