Оптимальный доступ к памяти при использовании справочных таблиц на GPU?

9

Я изучаю изоповерхностные алгоритмы на графическом процессоре для проекта бакалавра (особенно концентрируясь только на двоичных входных / выходных данных вокселей, а не на полях с действительными значениями). Итак, у меня есть реализация CPU старых добрых марширующих кубов, запущенная в OpenFrameworks, и сейчас на стадии попытки перенести ее на вычислительные шейдеры GLSL и рассмотреть подводные камни перед тем, как погрузиться в нее. Я написал только vert и frag шейдеры раньше, так что для меня все это ново.

Моя первая проблема заключается в том, как эффективно использовать справочную таблицу для десятков или сотен потоков в рабочей группе? Я понимаю, что у GPU есть разные виды памяти для разных задач, но я не совсем уверен в том, как они работают или какой тип использовать.

Классическая таблица copypasta Пола Бурка представляет собой массив размером 256 * 16, поэтому при использовании скалярного байтового типа он может быть упакован в текстуру 4 КБ или 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 зависит от размера справочной таблицы и частоты / согласованности доступа. В вашем случае (вы упомянули 4 КБ) лучше всего использовать совместно используемую локальную память (при условии, что вам не нужна эта память для других целей в том же ядре). Эта память имеет разные имена в разных API, но является одной и той же архитектурной особенностью и соответствует одним и тем же рекомендациям по производительности:

  • CUDA: общая память потоковой группы
  • DirectCompute: групповая память
  • OpenCL: локальная память
  • Металл: нить памяти группы
  • OpenGL: общая память

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

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

GroverManheim
источник
Есть также случаи, когда буфер только для чтения будет лучше, чем хранение 4 КБ данных только для чтения в общей локальной памяти. Например, хранение его в локальной памяти может означать, что для каждой группы потоков существует уникальная копия ваших данных. Если буфер помещается в кэш, вполне возможно, что он работает лучше, чем локальная память для шаблонов доступа только для чтения.
Джон Калсбек
Спасибо за отзывы ребята. Я закончил проект, которым я сейчас пользуюсь, и закончил, используя только буферную текстуру r8ui readonly, которая работала довольно хорошо :)
russ