почему розыгрыши дорогие? - PullRequest
49 голосов
/ 31 января 2011

при условии, что текстуры, вершины и данные шейдера уже находятся на графической карте, вам не нужно отправлять много данных на карту.есть несколько байтов для идентификации данных, и предположительно матрица 4x4, и некоторые другие параметры.

Так откуда же берется вся служебная информация?требуют ли операции какого-либо рукопожатия с gpu?

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

Ответы [ 3 ]

56 голосов
/ 02 февраля 2011

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

Вызовы на розыгрыш не обязательно дороги.В более старых версиях Direct3D для многих вызовов требовалось переключение контекста, что было дорого, но в новых версиях это не так.

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

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

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

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

Точно так же, как сказал Джош, отрисовка вызововтакже может привести к сбросу буфера команд, но по моему опыту это обычно происходит при вызове SwapBuffers, а не при отправке геометрии.Драйверы видео, как правило, пытаются буферизовать столько, сколько могут (несколько кадров иногда!), Чтобы выжать как можно больше параллелизма из графического процессора.

Вы должны прочитать презентацию nVidia Batch Batch Batch! , он довольно старый, но охватывает именно эту тему.

12 голосов
/ 31 января 2011

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

Пока буфер не очищен, графический процессор может выполнять некоторую подготовительную работу параллельно с процессором, если процессор не выполняет запрос блокировки (например, отображение данных обратно в процессор).).Но GPU не будет - и не может - подготовить все, пока он не должен на самом деле рисовать.Тот факт, что некоторые данные о вершинах или текстурах находятся на карте, еще не означает, что они расположены должным образом, и могут быть недоступны до тех пор, пока не будут установлены макеты вершин или не будут связаны шейдеры и так далее.Основная часть реальной работы выполняется во время вызова команд flush и draw.

В DirectX SDK есть раздел для точного профилирования производительности D3D , который, хотя и не связан напрямую с вашим вопросом, может предоставитьнекоторые намеки на то, что является и что не дорого, и (в некоторых случаях) почему.

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

Но, по сути (чтобы попытаться ответить на ваши вопросы), причинавызовы стоят дорого не потому, что обязательно много данных для передачи, а скорее из-за большого объема работы за пределами , просто доставка данных по шине, которая откладывается добуфер команд сброшен.

2 голосов
/ 21 июня 2011

Краткий ответ: Драйвер буферизует часть или всю фактическую работу, пока вы не вызовете draw.Это будет отображаться как относительно предсказуемый период времени, проведенный в вызове отрисовки, в зависимости от того, насколько изменилось состояние.

Это делается по нескольким причинам:

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

Альтернативный ответ (ы):

  • Буфер, используемый драйвером для хранения команд рендеринга, заполнен, и приложение эффективно ожидает, пока графический процессор обработает некоторые из предыдущих работ.Это обычно будет отображаться как очень большие фрагменты временной блокировки при случайном вызове отрисовки в кадре.
  • Достигнуто число кадров, которые драйверу разрешено буферизовать, и приложение ожидает на графическом процессореобработать один из них.Обычно это проявляется как большая часть блокирования времени при первом вызове отрисовки в кадре или при наличии в конце предыдущего кадра.
...