Джон вже написав чудову відповідь, тому вважайте цю відповідь продовженням своєї.
Зараз я багато працюю з обчислювальними шейдерами для різних алгоритмів. Загалом, я виявив, що обчислювальні шейдери можуть бути набагато швидшими, ніж їх еквівалентний піксельний шейдер, або перетворювати альтернативи на основі зворотного зв'язку.
Після того, як ви обмотаєте голову навколо того, як працюють обчислювальні шейдери, вони також мають набагато більше сенсу у багатьох випадках. Використання піксельних шейдерів для фільтрації зображення вимагає налаштування рамбуфера, надсилання вершин, використання декількох ступенів шейдерів тощо. Чому це потрібно для фільтрації зображення? На мою думку, звикання показувати повноекранні квадроцикли для обробки зображень - це, безумовно, єдина "вагома" причина. Я переконаний, що новачок в області обчислювальної графіки знайшов би обчислювальні шейдери набагато більш природними для обробки зображень, ніж надання текстурам.
Ваше запитання стосується зокрема фільтрації зображень, тому я не буду надто детально розглядати інші теми. У деяких наших тестах просто встановлення зворотного зв’язку трансформації або переключення об'єктів framebuffer для надання текстури може призвести до витрат на продуктивність приблизно в 0,2 мс. Майте на увазі, що це виключає будь-яку візуалізацію! В одному випадку ми зберегли такий самий алгоритм, який було портовано для обчислення шейдерів, і помітно збільшили продуктивність.
При використанні обчислювальних шейдерів, більше кремнію на графічному процесорі можна використовувати для виконання фактичної роботи. Усі ці додаткові кроки необхідні при використанні маршруту піксельних шейдерів:
- Збірка вершин (зчитування атрибутів вершин, дільниць вершин, перетворення типів, розширення їх на vec4 тощо)
- Вершинний шейдер потрібно планувати незалежно від того, наскільки він мінімальний
- Растерізатор повинен обчислити список пікселів, щоб відтіняти та інтерполювати вершинні виходи (можливо, лише текстурні координати для обробки зображень)
- Усі різні стани (випробування на глибину, альфа-тест, ножиці, змішування) повинні бути встановлені та керовані
Ви можете стверджувати, що розумні драйвери можуть заперечувати всі згадані раніше переваги у роботі. Ви б мали рацію. Такий драйвер може визначити, що ви рендеруєте повноекранний квадроцикл без тестування глибини тощо, і налаштувати "швидкий шлях", який пропускає всю марну роботу, виконану для підтримки піксельних шейдерів. Я не був би здивований, якщо деякі драйвери роблять це для прискорення пропусків після обробки в деяких іграх AAA для їх конкретних графічних процесорів. Ви, звичайно, можете забути про будь-яке подібне лікування, якщо ви не працюєте в грі AAA.
Що, однак, водій не може зробити, це знайти кращі паралельності можливостей, пропонованих обчислювальним шейдером. Візьмемо класичний приклад гауссового фільтра. За допомогою обчислювальних шейдерів ви можете зробити щось подібне (розділяючи фільтр чи ні):
- Для кожної робочої групи розділіть вибірку вихідного зображення на розмір робочої групи і збережіть результати в групі спільної пам'яті.
- Обчисліть вихід фільтра, використовуючи результати вибірки, що зберігаються в спільній пам'яті.
- Запишіть до тексту тексту виводу
Крок 1 є ключовим тут. У версії піксельних шейдерів вихідне зображення відбирається на вибірку кілька разів на піксель. У версії обчислювального шейдера кожен текстовий текст-джерело читається лише один раз всередині робочої групи. Для зчитування текстур зазвичай використовується кеш на основі плитки, але цей кеш все ще набагато повільніше, ніж спільна пам'ять.
Гауссовий фільтр - один із найпростіших прикладів. Інші алгоритми фільтрації пропонують інші можливості для обміну результатами посередництва в робочих групах, використовуючи спільну пам'ять.
Однак є улов. Обчислювальні шейдери вимагають явних бар'єрів пам'яті для синхронізації їх виводу. Існує також менше гарантій захисту від помилкового доступу до пам'яті. Для програмістів з хорошими знаннями паралельного програмування обчислювальні шейдери пропонують набагато більшу гнучкість. Однак ця гнучкість означає, що також легше обробляти обчислювальні шейдери, як звичайний код C ++ і писати повільний або неправильний код.
Список літератури
- Сторінка вікі OpenGL Compute Shaders
- DirectCompute: Оптимізація та кращі практики, Ерік Янг, корпорація NVIDIA, 2010 [pdf]
- Ефективне обчислення шейдерних програмувань, Білл Білодо, AMD, 2011? [pps]
- DirectCompute for Gaming - заряджайте свій двигун обчислювальними шейдерами, Layla Mah & Stephan Hodes, AMD, 2013, [pps]
- Оптимізація обчислень шейдерів для графічних процесорів AMD: паралельне зменшення, Вольфганг Енгель, 2014