Оптимальний доступ до пам'яті при використанні таблиць пошуку в GPU?


9

Я вивчаю алгоритми ізоповерхневих процесорів на графічному процесорі для бакалаврського проекту (конкретно зосереджуючись лише на бінарних даних про вокселі, а не на полях реального значення). Таким чином, у мене є реалізація процесора старих хороших маршових кубів і запуску в OpenFrameworks, і тепер на стадії спроби перенести його на обчислювальні шейдери GLSL та розглянути підводні камені перед тим, як зануритися. Я лише написав шейдери верту та фрагменту. раніше, тому для мене все нове.

Перше моє питання - як ефективно використовувати таблицю пошуку в десятках чи сотнях потоків у робочій групі? Я розумію, що графічний процесор має різні типи пам’яті для різних завдань, але не повністю впевнений у тому, як кожен працює або який тип використовувати.

Класична таблиця copypasta Пола Бурка - це масив 256 * 16, тому, якщо використовувати скалярний тип байтів, це, ймовірно, може бути упаковано в 4kb текстуру або SSBO.

Питання в тому, як не допустити, щоб різні потоки не спрацьовували один одного? Багато кубів у кожній робочій групі потенційно можуть мати однакову конфігурацію, тому намагаються отримати доступ до одного і того ж місця в буфері одночасно. Чи існує рішення чи оптимізація для вирішення цього питання?


Якщо це таблиця пошуку лише для читання, ви можете просто використовувати буфер / текстуру. Ви можете або упакувати його в один із звичайних текстурних форматів, або ви можете використовувати деякі новіші функції DX11 / OpenGL, щоб мати спеціальний формат. БПЛА в землі DX11 або текстура / shader_image_load_store в OpenGL-землі.
RichieSams

Крім того, погляньте на цю презентацію: cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf Це для CUDA, але це повинно дати вам краще уявлення про те, що відбувається з базовим обладнанням
RichieSams

Не повна відповідь, але чим менший обсяг пам’яті ви використовуєте, тим краще, оскільки це швидше вміститься в кешах і матиме менше пропусків кешу. Якщо у вас є інтерполяційні значення, як, наприклад, випікання точок на кривій у текстури, ви можете перевірити це як спосіб отримати таблиці вищої якості кривої пошуку з меншою пам’яттю: blog.demofox.org/2016/02/22/…
Алан Вулф

Відповіді:


6

Найкраще розмістити таблицю пошуку для обчислювального шейдера GPU залежить від розміру таблиці пошуку та частоти / когерентності доступу. У вашому випадку (ви згадали 4kb) спільна локальна пам'ять, ймовірно, буде найкращою (якщо припустити, що ця пам'ять не потрібна для інших цілей у тому ж ядрі). Ця пам’ять має різні назви в різних API, але це одне і те ж архітектурне, і воно відповідає тим самим рекомендаціям щодо продуктивності:

  • CUDA: спільна пам'ять для спільних груп
  • DirectCompute: групова спільна пам'ять
  • OpenCL: локальна пам'ять
  • Метал: пам'ять для ниткових груп
  • OpenGL: спільна пам'ять

Збереження таблиці пошуку в глобальній пам'яті як буфера, який доступний лише для читання, може виконуватись так само добре, залежно від розміру кеш-пам'яті конкретного GPU, на якому ви працюєте.

Зауважте, що я припускаю, що це таблиця пошуку лише для читання. Таблиця пошуку читання-запису - це зовсім інший звір, і у вас немає хороших варіантів.


Також бувають випадки, коли буфер лише для читання буде краще, ніж зберігання 4 кб даних лише для читання у спільній локальній пам'яті. Наприклад, зберігання їх у локальній пам'яті може означати, що існує унікальна копія даних для кожної групи потоків. Якщо буфер вписується в кеш, цілком можливо, що кеш працює краще, ніж локальна пам'ять для шаблонів доступу лише для читання.
Джон Калсбек

Дякую за відгуки хлопці. Я закінчив проект , я використовував це зараз, і завівся тільки з допомогою r8ui буфера для читання текстури, який працював дуже добре :)
Russ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.