Мой вопрос касается, в частности, ComputeShader, HLSL-кода. Так, DeviceContext.Dispath(X, Y, Z)
порождает X * Y * Z группы, каждая из которых имеет x * y * z отдельных потоков, установленных в атрибуте [numthreads(x,y,z)]
, Вопрос в том, как я могу получить общее количество отправленных ThreadGroups и количество потоков в группе? Позвольте мне объяснить, почему я этого хочу — объем данных, которые я собираюсь обрабатывать, может значительно отличаться, поэтому мои методы должны адаптироваться к размеру входных массивов. Конечно, я могу отправлять аргументы Dispath в постоянном буфере, чтобы сделать его доступным из кода HLSL, но как насчет количества потоков в группе? Я ищу такие методы, как GetThreadGroupNumber()
а также GetThreadNumberInGroup()
, Я ценю любую помощь.
Количество потоков в группе — это просто произведение numthreads
размеры. Например, numthreads(32,8,4)
буду иметь 32*8*4 = 1024
темы в группе. Это может быть определено статически во время компиляции.
Идентификатор конкретной группы потоков можно определить, добавив uint3
входной аргумент с SV_GroupId
семантический.
Идентификатор для конкретного потока в группе потоков может быть определен путем добавления uint3
входной аргумент с SV_GroupThreadID
семантический, или uint
SV_GroupIndex
если вы предпочитаете плоскую версию.
Если вы предоставляете информацию каждому потоку об общем размере отправки, лучше использовать постоянный буфер. Это аналогично графическому конвейеру, где пиксельный шейдер не знает размеров области просмотра.
Стоит также упомянуть, что если вы оказались в положении, когда каждому потоку необходимо знать общий размер отправки, вам следует подумать о реструктуризации своего алгоритма. В целом, лучше отправлять переменное количество групп потоков, каждая с фиксированным объемом работы, а не отправлять фиксированное количество потоков с переменным объемом работы. Конечно, есть исключения, но это обеспечит лучшее использование аппаратного обеспечения.
Других решений пока нет …