IT 이모저모

Barrier 란? - 1

exien 2018. 3. 7. 08:48

D3D12 또는 Vulkan 프로그래밍을 하고 있다면 Barrier때문에 많은 시간을 할애했을 것입니다. 유효성 레이어는 렌더링 코드를 변경하거나, 윈도우가 업데이트 되면 새로운 이슈가 발생하기 때문에 유효성 레이어 또한 다시 작성해 했습니다. 

게다가 IHV는 D3D11에서 얻은 결과를 충족 시키거나 능가하는 GPU 성능을 원한다면 장벽을 사용하는 방법에 대해 정말로주의 깊게해야한다는 말을 계속합니다. 이는 단순히 무결점을 달성하는 것의 맨 위에 추가되는 과제입니다 결과.

그래서 무엇을 제공합니까? 도대체 왜 우리는 처음부터 장벽이 필요한가? 그리고 우리가 오용한다면 왜 그렇게 잘못 될까? 중요한 콘솔 프로그래밍을 수행했거나 현대 GPU의 하위 레벨 세부 사항에 이미 익숙하다면이 질문에 대한 답변을 알고있을 것입니다.이 경우이 기사는 실제로 당신을위한 것이 아닙니다. 그러나 당신이 그 경험의 혜택을받지 못한다면, 장벽을 만들 때 뒤에서 무슨 일이 벌어지고 있는지 더 잘 이해할 수 있도록 최선을 다할 것입니다.


진입 장벽이 높다.


프로그래밍과 컴퓨터의 거의 모든 것들과 마찬가지로 "장벽"이라는 용어는 이미 약간 과부하 상태입니다. 어떤 상황에서는 " 장벽 "은 실행중인 코드의 특정 지점에 도달하면 스레드 묶음이 모두 중단되어야 하는 동기화 지점 입니다. 이 경우 장벽을 움직일 수없는 벽으로 생각할 수 있습니다. 스레드는 모두 실행되지만 장벽에 "부딪쳤을 때"트랙에서 멈추지 않습니다.


void ThreadFunction()
{
    DoStuff();
 
    // Wait for all threads to hit the barrier
    barrier.Wait();
 
    // We now know that all threads called DoStuff()
}


이런 종류의 일은 많은 스레드가 자신의 작업 ( 포크 조인 모델 에서 "조인")을 모두 마쳤 거나 다른 스레드의 결과를 읽어야 하는 스레드가 언제 있는지를 알고 자 할 때 유용 합니다. 프로그래머는 원자 연산을 통해 업데이트 된 변수에서 "회전 (spinning)"(조건이 충족 될 때까지 반복)하거나  스레드가 기다리는 동안 스레드를 잠자기 상태로 만들 때 세마포 및 조건 변수 를 사용하여 스레드 장벽을 구현할 수 있습니다 .

다른 문맥에서 "장벽"이라는 용어는  메모리 장벽  ( "울타리"라고도 함)을 나타냅니다. 특히 잠금 해제 프로그래밍 의 토끼 구멍에 어떻게 든 빠져 든 경우 특히 그렇습니다 . 이 시나리오에서는 일반적으로 컴파일러 및 / 또는 프로세서 자체에서 수행하는 메모리 작업의 순서 변경을 다루므로 여러 프로세서가 공유 메모리를 통해 통신 할 때 실제로 작업에서 렌치를 던질 수 있습니다. 메모리 장벽은 장벽 전후에 메모리 작업을 강제로 수행하여 울타리의 한쪽면에 효과적으로 메모리 작업을 유지하도록하여 사용자를 도와줍니다. C ++에서는 Windows API의 MemoryBarrier 와 같은 플랫폼 특정 매크로를 사용 하거나 크로스 플랫폼을 통해 코드에 삽입 할 수 있습니다std :: atomic_thread_fence . 일반적인 사용 사례는 다음과 같습니다.


// DataIsReady and Data are written to
// by a different thread
if(DataIsReady)
{
    // Make sure that reading Data happens
    // *after* reading from DataIsReady
    MemoryBarrier();
 
    DoSomething(Data);
}


"장벽"이라는 용어의이 두 가지 의미는 각기 다른 특징을 가지고 있지만 공통점이 있습니다. 한 가지가 결과를 산출하고 다른 결과가 그 결과를 읽을 때 주로 사용됩니다. 하나의 작업이 다른 작업에 의존 한다는 점을 말하는 또 다른 방법입니다  . 코드를 작성할 때 의존성은 항상 발생합니다. 오프셋을 계산하기 위해 두 개의 숫자를 추가하는 한 줄의 코드가있을 수 있습니다. 바로 다음 줄의 코드는 오프셋을 사용하여 배열에서 읽습니다. 그러나 컴파일러가 추적 할 수 있기 때문에 종종 이것을 인식 할 필요는 없습니다.이러한 종속성을 확인하고 올바른 결과를 제공하는 코드를 생성해야합니다. 장벽을 수동으로 삽입하는 것은 일반적으로 컴파일러가 컴파일 타임에 데이터를 쓰고 읽는 방법을 볼 수없는 방식으로 작업을 수행하기 전까지는 발생하지 않습니다. 이것은 일반적으로 동일한 데이터에 액세스하는 여러 스레드로 인해 발생하지만 다른 이상한 경우에도 발생할 수 있습니다 (다른 하드웨어가 메모리에 쓸 때와 같은 경우). 어느 쪽이든 적절한 장벽을 사용하면 결과가 종속 단계에 표시 되어 잘못된 데이터를 읽지 않도록 할 수  있습니다 .

'IT 이모저모' 카테고리의 다른 글

V30S 씽큐 9일 출시  (0) 2018.03.08
ARM, 새로운 VPU·GPU 발표 - 말리 V52·G52  (0) 2018.03.07
간단하고 빠른 XML 파서 : RapidXML  (0) 2018.03.06
C # 역방향 레시피 - 2  (0) 2018.03.06
C # 역방향 레시피 - 1  (0) 2018.03.06