Dispatch(5, 3, 2)
→ 총 30개의 Thread Group이 생성된다.
→ 각 Group은 우리가 numthreads(10, 8, 3)으로 지정한 대로 240개의 쓰레드를 포함한다.
즉, 총 30 × 240 = 7200개의 쓰레드가 동시에 동작할 수 있다는 말이다.
내가 속한 그룹이 전체 그룹 중에서 몇 번째인지 3차원 좌표로 알려준다.
예: SV_GroupID = (2,1,0) → x=2, y=1, z=0 번째 그룹
하나의 그룹 내에서, 내가 어떤 위치의 쓰레드인지를 알려준다.
예: SV_GroupThreadID = (7,5,0)
→ 해당 그룹 내부에서 x=7, y=5, z=0 위치에 있는 쓰레드
전체 그룹과 쓰레드를 포함한 절대 위치 ID
"전장 전체에서 나의 절대 좌표"
계산 공식:
SV_DispatchThreadID = SV_GroupID * numthreads + SV_GroupThreadID
예:
= (2,1,0) * (10,8,3) + (7,5,0)
= (2*10, 1*8, 0*3) + (7,5,0)
= (27,13,0)
SV_GroupThreadID를 1차원 인덱스로 flatten(평탄화)한 값
그룹 내부에서 "몇 번째 쓰레드인가?"
계산 공식:
SV_GroupIndex = z * (x * y) + y * x + x
= SV_GroupThreadID.z * (numthreads.x * numthreads.y) +
SV_GroupThreadID.y * numthreads.x +
SV_GroupThreadID.x
예:
SV_GroupThreadID = (7,5,0), numthreads = (10,8,3) →
SV_GroupIndex = 0 * 80 + 5 * 10 + 7 = 57
이런 시스템 값은 데이터 분할의 기준이 된다.
예시 상황:
👉 어느 쓰레드가 어떤 데이터를 처리할지 "SV 값"을 기준으로 분배하면 된다.
→ 즉, 쓰레드마다 처리할 데이터 인덱스를 이걸로 계산하면 된다!
[numthreads(10, 8, 3)]
void CS(ComputeInput input)
{
uint index = input.groupIndex;
uint outAddress = index * 10 * 4; // 40 바이트
Output.Store3(outAddress + 0, input.groupID);
Output.Store3(outAddress + 12, input.groupThreadID);
Output.Store3(outAddress + 24, input.dispatchThreadID);
Output.Store(outAddress + 36, input.groupIndex);
}
outAddress = index * 구조체 크기ByteAddressBuffer Input;
RWByteAddressBuffer Output;
[numthreads(10,8,3)]
void CS(ComputeInput input)
{
uint index = input.groupID.x * (10 * 8 * 3) + input.groupIndex;
uint outAddress = index * 11 * 4; // 구조체 크기: 44바이트
uint inAddress = index * 4;
float value = asfloat(Input.Load(inAddress));
Output.Store3(outAddress + 0, input.groupID);
Output.Store3(outAddress + 12, input.groupThreadID);
Output.Store3(outAddress + 24, input.dispatchThreadID);
Output.Store(outAddress + 36, input.groupIndex);
Output.Store(outAddress + 40, asuint(value));
}
→ 이렇게 하면 랜덤 값이 들어간 Input을 읽어서 Output에 기록하는 구조로 연산할 수 있다.
SV_GroupThreadID.x, .y, .z만 가지고도 공간상 위치 파악 가능numthreads(x,y,z)에서 총합은 1024 이하로 제한됨| 시스템 값 | 설명 |
|---|---|
| SV_GroupID | 내가 속한 그룹의 ID |
| SV_GroupThreadID | 그룹 내 쓰레드 위치 |
| SV_DispatchThreadID | 전체 전역 위치 |
| SV_GroupIndex | 그룹 내 1D 인덱스 (플랫) |
이 값들을 잘 활용하면 복잡한 데이터 분할, 병렬 처리, 최적화된 GPU 연산이 가능하다.