Джон уже написал отличный ответ, поэтому считайте этот ответ продолжением своего.
В настоящее время я много работаю с вычислительными шейдерами для различных алгоритмов. В общем, я обнаружил, что вычислительные шейдеры могут быть намного быстрее, чем их эквивалентные пиксельные шейдеры, или преобразовывать альтернативы на основе обратной связи.
После того, как вы поймете, как работают вычислительные шейдеры, во многих случаях они приобретают гораздо больший смысл. Использование пиксельных шейдеров для фильтрации изображения требует настройки буфера кадров, отправки вершин, использования нескольких этапов шейдера и т. Д. Почему это необходимо для фильтрации изображения? На мой взгляд, использование для отображения полноэкранных четырехугольников для обработки изображений, безусловно, является единственной «действительной» причиной для их дальнейшего использования. Я убежден, что новичок в области вычислительной графики найдет вычислительные шейдеры гораздо более естественными для обработки изображений, чем рендеринг в текстуры.
В частности, ваш вопрос касается фильтрации изображений, поэтому я не буду подробно останавливаться на других темах. В некоторых наших тестах простая настройка обратной связи преобразования или переключение объектов кадрового буфера для рендеринга в текстуру может привести к снижению производительности примерно на 0,2 мс. Имейте в виду, что это исключает любую визуализацию! В одном случае мы сохранили точно такой же алгоритм, портированный для вычисления шейдеров, и увидели заметное увеличение производительности.
При использовании вычислительных шейдеров для выполнения реальной работы можно использовать больше кремния на графическом процессоре. Все эти дополнительные шаги необходимы при использовании маршрута пиксельного шейдера:
- Сборка вершин (чтение атрибутов вершин, делителей вершин, преобразование типов, расширение их до vec4 и т. Д.)
- Вершинный шейдер должен быть запланирован независимо от того, насколько он минимален
- Растеризатор должен вычислить список пикселей для затенения и интерполировать выходные данные вершин (возможно, только текстурные координаты для обработки изображений)
- Все различные состояния (тест глубины, альфа-тест, ножницы, смешивание) должны быть установлены и управляться
Можно утверждать, что все вышеупомянутые преимущества в производительности могут быть сведены на нет умным драйвером. Вы были бы правы. Такой драйвер может определить, что вы рендеринге полноэкранного четырехугольника без глубинного тестирования и т. Д., И настроить «быстрый путь», который пропускает всю бесполезную работу, выполненную для поддержки пиксельных шейдеров. Я не удивлюсь, если некоторые драйверы сделают это для ускорения проходов постобработки в некоторых играх AAA для своих конкретных графических процессоров. Конечно, вы можете забыть о любом таком лечении, если вы не работаете над игрой ААА.
Однако драйвер не может найти лучшие возможности параллелизма, предлагаемые конвейером вычислительных шейдеров. Возьмите классический пример гауссовского фильтра. Используя вычислительные шейдеры, вы можете сделать что-то вроде этого (разделить фильтр или нет):
- Для каждой рабочей группы разделите выборку исходного изображения по размеру рабочей группы и сохраните результаты в общей разделяемой памяти.
- Вычислите выходные данные фильтра, используя результаты выборки, хранящиеся в общей памяти.
- Написать в выходную текстуру
Шаг 1 является ключевым здесь. В версии пиксельного шейдера исходное изображение дискретизируется несколько раз на пиксель. В версии вычислительного шейдера каждый исходный тексель читается только один раз внутри рабочей группы. Чтение текстур обычно использует кэш на основе плитки, но этот кеш все еще намного медленнее, чем разделяемая память.
Гауссов фильтр является одним из простых примеров. Другие алгоритмы фильтрации предлагают другие возможности для обмена промежуточными результатами внутри рабочих групп, использующих общую память.
Однако есть одна загвоздка. Вычислительные шейдеры требуют явных барьеров памяти для синхронизации их вывода. Существует также меньше мер защиты от случайного доступа к памяти. Для программистов с хорошими знаниями в области параллельного программирования вычислительные шейдеры предлагают гораздо большую гибкость. Эта гибкость, однако, означает, что также проще обрабатывать вычислительные шейдеры, как обычный код C ++, и писать медленный или некорректный код.
Ссылки
- Вики-страница OpenGL Compute Shaders
- DirectCompute: оптимизация и лучшие практики, Эрик Янг, NVIDIA Corporation, 2010 [pdf]
- Эффективное программирование шейдерных программ, Билл Билодо, AMD, 2011? [имп]
- DirectCompute для игр - зарядите свой движок с помощью вычислительных шейдеров, Layla Mah & Stephan Hodes, AMD, 2013, [pps]
- Оптимизация вычислений шейдеров для графических процессоров AMD: параллельное сокращение, Вольфганг Энгель, 2014