Какие функции OpenGL не ускоряются на GPU? - PullRequest
26 голосов
/ 26 апреля 2010

Я был шокирован, когда прочитал это (из OpenGL wiki ):

glTranslate, glRotate, glScale

AreЭто аппаратное ускорение?

Нет, нет известных графических процессоров, которые выполняют это.Драйвер вычисляет матрицу на CPU и загружает ее в GPU.

Все остальные операции с матрицами также выполняются на CPU: glPushMatrix, glPopMatrix, glLoadIdentity, glFrustum, glOrtho.

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

В течение очень, очень долгого времени я думал, что большинство функций OpenGL используютграфический процессор, чтобы сделать вычисления.Я не уверен, является ли это распространенным заблуждением, но после некоторого размышления это имеет смысл.Старые функции OpenGL (версии 2.x и старше) действительно не подходят для реальных приложений из-за слишком большого числа переключателей состояния.

Это позволяет мне понять, что, возможно, многие функции OpenGL не используют графический процессор ввсе.

Итак, вопрос в следующем:

Какие вызовы функций OpenGL не используют графический процессор?

Я полагаю, что знаю ответ наПриведенный выше вопрос поможет мне стать лучшим программистом с OpenGL.Пожалуйста, поделитесь некоторыми своими идеями.

Редактировать:

Я знаю, этот вопрос легко приводит к уровню оптимизации.Это хорошо, но суть этого вопроса не в этом.

Если кто-то знает набор функций GL в определенной популярной реализации (как предложил AshleysBrain, nVidia / ATI и, возможно, в зависимости от ОС), которые неиспользуйте GPU, вот что мне нужно!

Вероятные руководства по оптимизации появятся позже.Давайте сосредоточимся на функциях этой темы.

Edit2:

Эта тема не о том, как работают преобразования матриц.Для этого есть другие темы .

Ответы [ 5 ]

36 голосов
/ 27 апреля 2010

Мальчик, это большой предмет.

Сначала я начну с очевидного: поскольку вы вызываете функцию (любую функцию) из ЦП, она должна выполняться хотя бы частично в ЦП. Таким образом, вопрос на самом деле заключается в том, сколько работы выполняется на процессоре и сколько на графическом процессоре.

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

Все это говорит о том, что передача работы в GPU не является бесплатным упражнением. Эта стоимость должна быть сопоставлена ​​с запуском функции на процессоре (независимо от того, о чем мы говорим).

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

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

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

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

Выбор - это еще один вариант, в котором неясно, имеет ли смысл выполнение на GPU.

И, наконец, я должен сказать, что в целом существует небольшая корреляция между вызовами API и объемом работы на процессоре или графическом процессоре. API установки состояния имеет тенденцию изменять только структуру где-то в данных драйвера. Его эффект виден только при вызове Draw или чего-то подобного.

Многие из GL API работают так. В этот момент спрашивать, выполняется ли glEnable(GL_BLEND) на процессоре или графическом процессоре, довольно бессмысленно. Важно то, произойдет ли смешивание на GPU при вызове Draw. Таким образом, в этом смысле Большинство GL точек входа вообще не ускоряются.

Я мог бы также немного расширить передачу данных, но Данвил коснулся этого.

Я закончу с небольшим "з / ш путь". Исторически, GL должен был работать над спецификацией, независимо от того, какие аппаратные особые случаи были. Это означало, что если h / w не обрабатывал определенную функцию GL, то он должен был эмулировать ее или полностью реализовать в программном обеспечении. Есть множество случаев этого, но один, который поразил многих людей, это когда GLSL начал появляться.

Поскольку не было никакого практического способа оценить размер кода шейдера GLSL, было решено, что GL должен был принять любую длину шейдера как допустимую. Смысл был довольно ясен: либо реализовать ч / б, которые могли бы принимать шейдеры произвольной длины - нереалистичные в то время, либо внедрить эмуляцию ш / ш шейдеров (или, как решили некоторые производители, просто не соответствовать друг другу). Таким образом, если вы вызвали это условие на фрагментном шейдере, есть вероятность, что целом вашего GL в конечном итоге будет выполнено на процессоре, даже если у вас неактивный графический процессор, по крайней мере для этого отрисовки.

8 голосов
/ 26 апреля 2010

Возможно, вопрос должен звучать так: «Какие функции потребляют неожиданно большое количество процессорного времени?»

Сохранение стека матрицы для проекции и просмотра - это не то, с чем графический процессор справится лучше, чем процессор (наоборот ...). Другим примером будет компиляция шейдеров. Почему это должно работать на GPU? Есть синтаксический анализатор, компилятор ..., которые являются обычными программами ЦП, такими как компилятор C ++.

Потенциально «опасными» вызовами функций являются, например, glReadPixels, потому что данные могут быть скопированы из памяти хоста (= CPU) в память устройства (= GPU) по ограниченной шине. В этой категории также есть такие функции, как glTexImage_D или glBufferData.

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

7 голосов
/ 26 апреля 2010

Как правило, если операция выполняется для чего-то, она будет выполняться на графическом процессоре. Примером является фактическое преобразование - это делается один раз для каждой вершины. С другой стороны, если это происходит только один раз за большую операцию, это будет происходить в ЦП, например, при создании матрицы преобразования, которая выполняется только один раз при каждом изменении состояния объекта или один раз за кадр.

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

@ отправка данных в GPU: насколько я знаю (используется только Direct3D), все это делается в шейдерах, для этого и нужны шейдеры.

4 голосов
/ 26 апреля 2010

glTranslate, glRotate и glScale изменяют текущую активную матрицу преобразования. Это, конечно, операция процессора. Матрицы вида модели и проекции просто описывают, как графический процессор должен преобразовывать вершины при выдаче команды рендеринга.

Так, например, по вызову glTranslate ничего еще не переведено. Перед рендерингом матрицы текущей проекции и вида модели умножаются (MVP = projection * modelview), затем эта одиночная матрица копируется в GPU, а затем GPU выполняет умножение матрицы * вершины ("T & L") для каждой вершины. Таким образом, перевод / масштабирование / проекция вершин выполняется графическим процессором.

Также вам не стоит беспокоиться о производительности, если вы не используете эти функции во внутреннем цикле. glTranslate дает три дополнения. glScale и glRotate немного сложнее.

Я советую вам узнать немного больше о линейной алгебре. Это важно для работы с 3D API.

2 голосов
/ 26 апреля 2010

Существуют программные реализации OpenGL, поэтому возможно, что no Функции OpenGL выполняются на GPU. Также есть оборудование, которое не поддерживает определенные состояния рендеринга на аппаратном уровне, поэтому, если вы установите определенное состояние, переключитесь на рендеринг программного обеспечения и снова, на GPU ничего не будет работать (даже если оно там есть). Поэтому я не думаю, что есть какое-то четкое различие между «функциями с GPU-ускорением» и «функциями без GPU-ускорения».

Чтобы быть в безопасности, держите вещи как можно проще. Простые функции рендеринга с вершинами и базовые функции, такие как Z-буферизация, , скорее всего, , будут с аппаратным ускорением, поэтому, если вы будете придерживаться этого с минимальным изменением состояния, вы, скорее всего, сохраните аппаратное ускоряются. Это также способ максимизировать производительность аппаратно-ускоренного рендеринга - графические карты любят оставаться в одном состоянии и просто ломать кучу вершин.

...