책에는 계산 셰이더 파이프라인에 관한 내용만 있고 실제 쓰는 방법은 나와있지 않아서 지금 작업하고 있는 프레임워크에 적용하는 방법을 좀 찾아봐야겠다
스레드의 동기화
1. Memery Barrier
하나의 스레드 그룹 안의 스레드들에 대한 동기화
두 가지 속성에 의해 나뉜다
- 동기화의 대상이 되는 메모리의 종류 : GSM에 대한 동기화를 유발하는 함수가 있고, Device Memory에 대한 동기화를 유발하는 함수도 있으며, 그 둘 다에 대한 동기화를 유발하는 함수도 있다.
- 그룹 동기화 여부 : 주어진 스레드 그룹의 다른 모든 스레드가 동일한 동기화 지점에 도달할 때까지 기다릴 것인지의 여부
GroupMemoryBarrer()
: 스레드 그룹의 스레드들이 GSM Write가 모두 완료될 때까지 현재 스레드의 실행을 차단한다. 그룹의 일부 스레드가 GSM을 수정하며 수정이 모두 완료된 후에만 다른 스레드들이 읽어야 하는 경우에 적합한 함수
GroupMemoryBarrerWithGroupSync()
: 그룹의 모든 GSM Write가 완료되었고 그룹의 모든 스레드가 이 동기화 지점에 도달해야만 현재 스레드의 실행을 재개한다. 스레드 그룹의 각 스레드가 GSM에서 다른 스레드가 사용할 자료를 적재하는 경우에 유용함
DeviceMemoryBarrer()
DeviceMemoryBarrierWithGroupSync()
: 동기화할 접근 대상이 Device Memory 자원이다. UAV로 연결된 자원에 대한 Write 연산들을 동기화한다.
GSM은 그룹당 32KB이기 때문에 더 큰 자료가 필요하다면 Device Memory 자원을 사용해야 한다.
AllMemoryBarrier()
AllMemoryBarrierWithGroupSync()
: GSM과 DM에 모두 접근하는 스레드들을 동기화할 때 사용한다.
두 종류의 메모리는 자료 기록 시스템이 다르므로 동시적인 Write 연산들 사이의 시간 지연이 다를 것이기 때문에 혼성 메모리 사용 상황에선느 동기화가 매우 중요하다.
2. Automic Function
: 한번에 스레드 몇개만 동기화하는 식의 소규모의 동기화가 필요할 때 사용한다. 그래서 좀 더 세밀한 동기화가 가능하다. 한 스레드에서 호출하면 그 함수의 결과는 같은 메모리 장소에 접근하려하는 다른 모든 스레드에 전파된다.
• InterlockedAddQ
• InterlockedMin()
• InterlockedMaxQ
• InterlockedAndQ
• InterlockedOr()
InterlockedXorQ
• InterlockedCompareStore()
InterlockedCompareExchange()
• InterlockedExchange()
GSM이나 DM 자원의 한 장소의 내용을 뮤텍스나 세마포어 같은 일종의 동기화 기본수단으로 만들 수 있다.
ex) 특정한 자료 값을 발견한 스레드들의 개수를 세본다. GSM이나 DM에 Counter 변수를 하나두고 0으로 초기화한다. 각 스레드는 특정 자료를 만나면 InterlockedAdd()를 이용해서 그 변수의 값을 증가한다.
이런 식으로 활용하면 서로 다른 스레드가 중간 값을 덮어 쓰는 일 없이 전체 개수가 정확하게 증가하게 된다.
3. 암묵적 동기화 (Implicit Synchronization)
: 알고리즘 자체를 스레드들 사이에 잠재적 경쟁이나 충돌이 없도록 설계함으로써 동기화 자체를 피한다.
알고리즘 설계
병렬성 (Parallelism)
- 동기화의 최소화
- 스레드 간 자료 공유
- 적재된 메모리 공유
- 복잡한 계산 결과 공유
'프로그래밍 > Shader' 카테고리의 다른 글
Adaptation (0) | 2019.03.14 |
---|---|
Bloom 이론 (0) | 2019.03.13 |
HDR 이론 (0) | 2019.03.06 |
Compute Shader_2 (0) | 2019.02.09 |
Compute Shader_1 (0) | 2019.02.08 |