Реализация алгоритмов с помощью вычислительных шейдеров или конвейерных шейдеров

10

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

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

Учитывая алгоритм, который может быть реализован обоими способами, есть ли общие (потенциальные) преимущества в производительности по сравнению с использованием вычислительных шейдеров по сравнению с обычным маршрутом? Есть ли недостатки, на которые мы должны обратить внимание (например, есть ли какие-то необычные издержки при переключении с / на вычисление шейдеров во время выполнения)?

Есть ли другие преимущества или недостатки, которые следует учитывать при выборе между ними?

TravisG
источник
Если тег производительности действительно актуален, подумайте о просмотре этого видео из статьи Марко Фратаркангели из Game Engine Gems «Cloth Simulation»: youtube.com/watch?v=anNClcux4JQ . Вы можете прочитать комментарии и обнаружить неловкую вещь: реализация на основе GLSL / шейдеров была быстрее, чем использование CUDA или OpenCL (последнее из-за плохой поддержки драйверов в то время, в 2010 году). Существуют определенные различия на низком уровне, которые ... имеют значение.
Теодрон
@teodron У меня нет доступных Gem Gem и я не могу найти исходный код. Использовал ли автор на самом деле вершинные + пиксельные шейдеры GLSL или он использовал вычислительные шейдеры GLSL?
TravisG
Да! До CUDA сообщество реализовало функции GPGPU. Вот ссылка на OpenCloth , чтобы увидеть , как можно достичь только , что при использовании чистого GLSL ИЛИ Cuda: code.google.com/p/opencloth/source/browse/trunk/...
teodron

Ответы:

7

Нет правильного ответа, если вы собираетесь напрямую воспользоваться преимуществами compute shadrs / GPGPU appraoch, это сильно зависит от типа алгоритма, который вы реализуете, compute shaders и CUDA / OpenCL - более обобщенный подход для преодоления некоторых ограничений этого старого хакерского языка. Самые важные преимущества, которые вы получите:

  • Доступ к пространственной информации. в старом взломе GLSL (ну, это был взлом!) только дает мало информации о соседних фрагментах, так как он использует координаты текстуры. В вычислительных шейдерах / CUDA / OpenCL доступ к пространственной информации гораздо более гибкий, теперь вы можете реализовывать алгоритмы, такие как выравнивание гистограммы на GPU с неупорядоченным доступом к текстуре / буферу.
  • Дает вам синхронизацию потоков и атомарность .
  • Вычислительное пространство: старый хак GLSL жестко привязывает вычислительное пространство вершины / фрагмента к вашему шейдеру. Фрагментный шейдер будет работать с количеством фрагментов, вершинный шейдер будет работать с количеством вершин. В вычислительном шейдере вы определяете собственное пространство.
  • Масштабируемость : ваш вычислительный шейдер / CUDA / OpenCL может масштабироваться до количества доступных графических процессоров SM (потокового мультипроцессора) в отличие от вашего старого шейдера GLSL, который должен выполняться на том же SM. (На основании комментариев Натана Рида он говорит, что это неправда, и шейдеры должны масштабироваться так же хорошо, как должны вычислять шейдеры. Я все еще не уверен, хотя мне нужно проверять документацию).
  • Переключение контекста : должно быть некоторое переключение контекста, но я бы сказал, что это зависит от приложения, поэтому лучше всего профилировать ваше приложение.

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

  1. Аппаратная и обратная совместимость . Вычислительные шейдеры доступны только на более новом оборудовании, и если вы собираетесь использовать коммерческий продукт (например, игру), вам следует ожидать, что многие пользователи не смогут запустить ваш продукт.
  2. Обычно вам требуются дополнительные знания в области архитектуры GPU / CPU , параллельного программирования и многопоточности (например, совместное использование памяти, согласованность памяти, синхронизация потоков, атомарность и ее влияние на производительность), которые обычно не нужны при использовании обычных шейдеров.
  3. Учебные ресурсы , исходя из опыта, гораздо меньше учебных ресурсов для Compute shadrs, OpenCL и CUDA (которые также обеспечивают совместимость с OpenGL), чем обычный маршрут шейдеров.
  4. Инструменты отладки , при отсутствии надлежащей отладки, разработка инструментов может стать намного сложнее, чем большинство шейдеров, по крайней мере, шейдеры могут быть отлажены визуально.
  5. Я ожидаю, что вычислительные шейдеры дадут лучшую производительность, чем тот же алгоритм в других шейдерах; если они были сделаны правильно, принимая во внимание вещи из пункта 2, так как они были разработаны, чтобы избежать дополнительных шагов для рендеринга графики. Но у меня нет никаких конкретных доказательств, подтверждающих мое утверждение.
  6. Вы также должны рассмотреть CUUDA / OpenCL для GPGPU, если вы идете по этому маршруту.

Тем не менее, я уверен, что это здорово для будущего и будет отличным опытом обучения. Удачи!

concept3d
источник
Я думаю, что ОП может спросить: зачем решать проблему, используя чистые шейдеры GLSL, а не кодировать ее в CUDA? Есть статья о Game Programming Gems, касающаяся симуляции одежды, где автор делает именно это. И хакерский старый способ GLSL лучше, чем CUDA, с точки зрения производительности. Вы, вероятно, должны указать, почему, если у вас есть идеи, почему.
Теодрон
2
Я не думаю, что ваша точка масштабируемости верна - вершинные и фрагментные шейдеры так же способны масштабироваться по всему графическому процессору, как и вычислительные шейдеры. На самом деле вычислить шейдеры может быть сложнее масштабировать, так как размер группы потоков и использование общей памяти могут накладывать дополнительные ограничения на то, сколько потоков шейдеров может работать одновременно.
Натан Рид
2
Кроме того, если вы заполняете текстуру (например, генерируете шум или делаете какой-то другой процедурный алгоритм), по моему опыту фрагментный шейдер будет быстрее, чем вычислительный шейдер, если вы просто оцениваете формулу в каждом пикселе. Я предполагаю, что это потому, что порядок фрагментов соответствует внутреннему мозаичному / мозаичному порядку пикселей, что обеспечивает лучшую локальность памяти, чем вычислительный шейдер, который не знает этого порядка. Вычислительные шейдеры работают быстрее, только если вы можете использовать их специальные функции, например, разделяемую память, чтобы значительно ускорить работу с фрагментным шейдером.
Натан Рид
2
ОК, последний комментарий. :) Я думаю, что большинство современных графических процессоров имеют переключение контекста или режима при переходе от графики к вычислениям и наоборот. Поэтому, если вы запускаете несколько графических шейдеров, затем отправляете вычислительный шейдер, затем запускаете еще несколько графических шейдеров и т. Д., Вы испытываете некоторое снижение производительности при переключении назад и вперед. Это то, что вам нужно профилировать, но это может быть еще одна причина придерживаться графических шейдеров в конкретном случае.
Натан Рид
@NathanReed спасибо за комментарии, я буду обновлять свой ответ.
concept3d