Поэтому, когда речь заходит о графике для iOS, где модель общей памяти регулирует доступ к памяти в графических приложениях, буферизация является важной концепцией.
Идея состоит в том, что вы буферизуете свои данные, которые обновляются каждый кадр, таким образом, что процессор всегда записывает в другой раздел буфера, чем считывает графический процессор.Затем вы ждете, пока кадры завершат рендеринг, прежде чем начинать запись в другой раздел буфера ЦП.
Как это реализовать, довольно ясно, когда речь идет о данных, которые полностью обновляют каждый кадр.У меня вопрос, как это сделать для исторических данных.Представьте себе, что я хотел сохранить вершины следа для некоторого объекта, когда он проходит через сцену.
Тогда у меня был бы своего рода кольцевой буфер, отслеживающий последние 120 кадров данных таким образом, чтобы размер былконстанта, и я мог бы просто сделать так, чтобы процессор записывал в разные части циклического буфера каждый кадр.
----- ----- ----- ----- ----- ----- -----
n-3 n-2 n-1 n n+1 n+2 n-4
----- ----- ----- ----- ----- ----- -----
^CPU Write
В приведенном выше примере для данного кадра, где n представляет самую последнюю часть визуализации,ЦП будет записывать в место в буфере, помеченном как n + 2, а графический процессор будет за два вызова отрисовки отображать n-3 -> n и n-4.Хотя технически это позволило бы избежать ситуации, когда центральный процессор и графический процессор взаимодействуют с одним и тем же блоком данных в одно и то же время, я обеспокоен передачей этого.
По сути, мой вопрос: Как я могу сообщить Metal, что я гарантировал, что ЦП не будет записывать данные, пока ГП пытается их прочитать?Есть ли что-то, что мне нужно сделать с выравниванием?Они блокируют доступ к определенным размерам памяти или к чему-то еще?
Чтобы сделать этот вопрос немного более запутанным, представьте, что я хранил следы для 120 кадров движения для 1000 различных объектов внутри одного буфера.Есть несколько способов, которыми я мог бы добиться этого, по-разному размещая данные в буфере.Например, у меня могло бы быть это как это
----- ----- -----
p1 p2 p3
----- ----- -----
С каждым блоком p, представляющим историю 120 кадров для этой частицы, и затем я мог применить ту же самую концепцию выше с этим, имея до двух вызовов отрисовки, чтобы избежатьданные чертежа, которые в настоящее время записываются.
Или я мог бы выложить их следующим образом:
----- ----- ----- ----- ----- ----- -----
n-3 n-2 n-1 n n+1 n+2 n-4
----- ----- ----- ----- ----- ----- -----
^CPU Write
Где внутри каждого из n блоков данные для каждой частицы расположены рядом.
Чтобы сделать вещи еще более сложными, я мог бы вообще избежать нескольких вызовов отрисовки и открыть вещи для альфа-смешивания (сортировки порядка отрисовки треугольника), используя индексный буфер.Индексный буфер действительно может гарантировать, что CPU и GPU технически не должны ждать друг друга. Но узнают ли они?
Могу ли я даже добиться этой оптимизации, когда у меня происходят индексные буферы ?Или это делает доступ к памяти непредсказуемым?
Я понимаю, что это долгая запись!Основные вопросы выделены жирным шрифтом.По сути, мне просто интересно, как / когда графический процессор и процессор решают ждать при обмене данными.