Когда-то, когда> был быстрее, чем <… Подожди, что?

280

Я читаю потрясающий учебник OpenGL . Это действительно здорово, поверь мне. Тема, которой я сейчас занимаюсь, это Z-буфер. Помимо объяснения, что это такое, автор упоминает, что мы можем выполнять пользовательские тесты глубины, такие как GL_LESS, GL_ALWAYS и т. Д. Он также объясняет, что фактическое значение значений глубины (которое является верхним, а что нет) также может быть настроены. Я так понимаю, до сих пор. И тогда автор говорит что-то невероятное:

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

Ранее было сказано, что значение Z в пространстве окна 0 является ближайшим, а 1 - самым дальним. Однако, если бы наши значения Z пространства клипа были сведены на нет, глубина 1 была бы самой близкой к представлению, и глубина 0 была бы самой дальней. Тем не менее, если мы изменим направление проверки глубины (от GL_LESS до GL_GREATER и т. Д.), Мы получим точно такой же результат. Так что это действительно просто соглашение. Действительно, изменение знака Z и проверка глубины были когда-то жизненно важной оптимизацией производительности для многих игр.

Если я правильно понимаю, с точки зрения производительности переключение знака Z и проверка глубины - не что иное, как изменение <сравнения к >сравнению. Так что, если я правильно понимаю, и автор не лжет и не выдумывает, то переход <на >ранее использовался как жизненная оптимизация для многих игр.

Автор придумывает, я что-то неправильно понимаю, или это действительно тот случай, который когда-то <был медленнее ( жизненно , как говорит автор), чем >?

Спасибо за разъяснение этого довольно любопытного вопроса!

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

Армен Цирунян
источник
6
Ссылка на этот учебник, кажется, (недавно) исчезла. :(
TZHX
@TZHX: Поскольку принятый ответ создан автором учебника, мы надеемся найти его снова. Смотрите мой последний комментарий к его ответу :)
Армен Цирунян
3
Ссылка на учебник OpenGL доступна здесь .
Фонды
(a <b) идентичен (b> a), поэтому абсолютно не нужно реализовывать обе операции сравнения в аппаратном обеспечении. Разница в производительности является результатом того, что происходит в результате операции сравнения. Это длинный и извилистый путь, чтобы объяснить все побочные эффекты, но вот несколько советов. Игры использовали для заполнения буфера глубины, чтобы избежать более дорогой обработки фрагментов, которые не прошли проверку глубины. Quake раньше разделял диапазон глубины на две половины, чтобы избежать очистки буфера кадра, потому что игра всегда заполняла каждый пиксель на экране и так далее.
t0rakka
2
@Fons выглядит как ссылка мертвая, опять же :(
nalzok

Ответы:

350

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

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

Тем не менее, контекст является ключевым. Я никогда не говорил, что <сравнение было быстрее, чем> сравнение. Помните: мы говорим о тестах глубины графического оборудования, а не о вашем процессоре. Не operator<.

Я имел в виду конкретную старую оптимизацию, в которой вы использовали бы один кадр GL_LESSс диапазоном [0, 0,5]. Следующий кадр вы визуализируете с GL_GREATERдиапазоном [1.0, 0.5]. Вы идете взад и вперед, буквально «переворачивая знак Z и тест глубины» каждого кадра.

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

Николь Болас
источник
1
Причина, по которой очистка буфера глубины происходит быстрее, в наши дни имеет две причины, каждая из которых основана на том факте, что графический процессор использует иерархический буфер глубины. Для этого нужно только очистить, установить состояния мозаики для очистки (что является быстрым), изменив знак сравнения глубины, однако, это означает, что весь буфер HiZ необходимо очистить, поскольку он хранит только минимальное или максимальное значение в зависимости от знака сравнения.
Джаспер Беккерс
3
@NicolBolas: комментарий PerTZHX, ссылка на ваш учебник в моем вопросе исчезла. Не могли бы вы сообщить нам всем, куда движутся учебники, и при необходимости отредактировать вопрос?
Армен Цирунян
2
Уроки доступны в веб-архиве. Если @NicolBolas позволяет, было бы полезно для сообщества, если бы мы могли переместить их в более доступное место. Может быть, GitHub или что-то. web.archive.org/web/20150215073105/http://arcsynthesis.org/…
ApoorvaJ
3

Ответ почти наверняка состоит в том, что для любого воплощения чип + драйвер, Иерархический Z работал только в одном направлении - это было довольно распространенной проблемой в те времена. Низкоуровневая сборка / ветвление не имеет к этому никакого отношения - Z-буферизация выполняется на оборудовании с фиксированной функцией и конвейерной - нет спекуляций и, следовательно, прогнозирования ветвлений.

Crowley9
источник
0

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

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

Драйвер должен предположить, что предыдущее содержимое должно быть сохранено. Сохранение означает, что корзина должна быть записана во внешнюю память, а затем восстановлена ​​из внешней памяти при повторной обработке корзины. Операция очистки сообщает водителю, что содержимое корзины четко определено: чистый цвет. Это ситуация, которую тривиально оптимизировать. Существуют также расширения для «отбрасывания» содержимого буфера.

t0rakka
источник
-8

Это связано с битами флагов в сильно настроенной сборке.

В x86 есть инструкции jl и jg, но большинство процессоров RISC имеют только jl и jz (без jg).

Джошуа
источник
2
Если это ответ, это вызывает новые вопросы. Было ли "ветвление получено" медленнее, чем "ветвь проигнорировано" на ранних процессорах RISC? Насколько я знаю, сейчас это определенно не так. Вы должны были написать forциклы с безусловной ветвью в обратном направлении и условной, редко используемой ветвью вперед, чтобы выйти из цикла? Звучит неловко.
Паскаль Куок
54
-1: Этот вопрос не имеет ничего общего с процессорами . GL_LESS и GL_GREATER - это операции сравнения глубины, которые выполняются на графических процессорах.
Никол Болас
8
Забавно, сколько повторений вы можете получить за ответ, который соответствует названию, но имеет мало общего с реальным вопросом.
Иисус Навин
7
+1 Нет, этот ответ правильный хотя бы в части вопроса. Вопрос в следующем: «Придумывает ли автор что-то, я что-то неправильно понимаю, или это действительно так, что когда-то <было медленнее (жизненно, как говорит автор), чем>?». Есть три варианта. Этот ответ отвечает на возможность варианта 3. Нигде в статье не говорится ни о технологии CPU / GPU, ни о том, что это должен быть GPU (первые 3D-игры, где на CPU). Хорошо ... Я не думаю, что было много 3D-игр на RISC :-)
xanatos
3
(и тег GPU был добавлен в 20:34. В первой ревизии был только тег CPU. Этот ответ был написан в 18:44)
xanatos