본문 바로가기

프로그래밍/Shader

Compute Shader_3

책에는 계산 셰이더 파이프라인에 관한 내용만 있고 실제 쓰는 방법은 나와있지 않아서 지금 작업하고 있는 프레임워크에 적용하는 방법을 좀 찾아봐야겠다

스레드의 동기화

1. Memery Barrier
 하나의 스레드 그룹 안의 스레드들에 대한 동기화

두 가지 속성에 의해 나뉜다
  1. 동기화의 대상이 되는 메모리의 종류 : GSM에 대한 동기화를 유발하는 함수가 있고, Device Memory에 대한 동기화를 유발하는 함수도 있으며, 그 둘 다에 대한 동기화를 유발하는 함수도 있다.
  2. 그룹 동기화 여부 : 주어진 스레드 그룹의 다른 모든 스레드가 동일한 동기화 지점에 도달할 때까지 기다릴 것인지의 여부

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)

  1. 동기화의 최소화
  2. 스레드 간 자료 공유
  3.  적재된 메모리 공유
  4. 복잡한 계산 결과 공유


'프로그래밍 > 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