Какая польза от нескольких измерений в размере рабочей группы вычислительного шейдера?

Вычислительные шейдеры требуют подсчета рабочих групп при отправке. Это должно быть представлено в 3-х измерениях. То же самое касается размера рабочей группы, указанного в самом вычислительном шейдере.

Функция для отправки вычислительного шейдера в OpenGl: glDispatchCompute.

Вопрос:

  • почему 3 измерения?
  • почему бы не передать 1 большое число?
  • как 3 измерения приводят к фактическому числу?

person Kibouo    schedule 08.05.2018    source источник


Ответы (1)


Существуют вычисления, которые по своей сути являются 2-х или 3-х мерными. И есть вычисления, которые по своей сути одномерны. Кому-то будет неудобно. Либо многомерным пользователям придется взять 1D-индекс и преобразовать его в 2/3D-индексы, либо одномерным пользователям, возможно, придется взять 2/3D-индекс и сжать его до 1D.

Конечно, обратите внимание на разницу между «будет» и «может». Пользователям с одним измерением необходимо распознавать измерения Y или Z только в том случае, если ограничения реализации по измерению X команды диспетчеризации слишком малы для выполнения достаточного количества вызовов. Учитывая, что все реализации должны обеспечивать не менее 65 535 рабочих групп для каждого измерения, это охватывает много вопросов.

Таким образом, несмотря на то, что многомерный характер вычислительных операций может создавать неудобства для одномерной работы, существует множество одномерных задач, которые не вызывают неудобств. Так что "может" предпочтительнее "будет".

как 3 измерения приводят к фактическому числу?

Предполагая, что вам вообще нужно использовать координаты Y и Z в вашей одномерной вычислительной операции (а вы редко это делаете), существует множество способов сделать это. Они различаются только в отношении порядка различных измерений. Следующий способ использует порядок gl_LocalInvocationIndex.

Если вам нужно получить индекс для конкретной рабочей группы, это достаточно просто:

uint WorkGroupIndex = dot(gl_WorkGroupID, uvec3(1, gl_NumWorkGroups.x, gl_NumWorkGroups.x * gl_NumWorkGroups.y));

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

uint UniqueIndex = (WorkGroupIndex * gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z) + gl_LocalInvocationIndex;
person Nicol Bolas    schedule 09.05.2018
comment
В качестве комментария; видеокарты исторически были предназначены для хранения и обработки 2D-текстур - ограничения на выделение буфера были довольно небольшими. Любопытно, что при использовании 3D-буферов одни и те же ограничения используются для каждого измерения (по крайней мере, на картах NV), а это означает, что 3D-буфер может хранить гораздо большие объемы данных, и, очевидно, вы можете перекодировать любую индексацию в свою личную интерпретацию размерности данных. . - person StarShine; 09.05.2018
comment
Отличный ответ. Я бы добавил, что еще одним преимуществом 2D-рабочих групп является то, что они обычно находятся рядом друг с другом, что создает пространственную локальность, которая отлично подходит для кэширования текстур, тогда как простое преобразование 1D в 2D может не дать этого. Таким образом, эта работа выполняется за вас и, как правило, соответствует тому, что аппаратное обеспечение хотело бы видеть. - person Dithermaster; 09.05.2018