가변 길이 루프가 GPU 쉐이더에 미치는 영향


9

예를 들어 데모 씬에서 GPU 내부에 절차 적 내용을 렌더링하는 것이 인기가 있습니다 (화면을 채우기 위해 단일 쿼드를 그려 GPU가 픽셀을 계산하게 함).

레이 행진 이 인기가 있습니다.

여기에 이미지 설명을 입력하십시오

이것은 GPU가 픽셀 당 알 수없는 루프 반복 횟수를 실행하고 있음을 의미합니다 (그러나 상한을 가질 수는 있음 maxIterations).

가변 길이 루프를 사용하면 셰이더 성능에 어떤 영향을 줍니까?

간단한 광선 행진 psuedocode를 상상해보십시오.

t = 0.f;
while(t < maxDist) {
    p = rayStart + rayDir * t;
    d = DistanceFunc(p);
    t += d;
    if(d < epsilon) {
       ... emit p
       return;
    }
}

다양한 주류 GPU 제품군 (Nvidia, ATI, PowerVR, Mali, Intel 등)은 어떤 영향을 받습니까? 버텍스 쉐이더, 특히 프래그먼트 쉐이더?

어떻게 최적화 할 수 있습니까?


불행히도이 질문은 여기에 제대로 대답하기가 너무 어렵습니다. 하나의 답변은 이미 읽을만한 가치가있는 소스를 지적했지만 (동적 분기 포함). "topic"에 +1 ..
teodron

1
@teodron은 패배하지 마십시오! NVidia 카드에서 8x8 블록의 화면 픽셀은 가장 필요한만큼 깊이 반복되며 8x8 픽셀의 블록은 어떤 순서로든 또는 이와 유사한 방식으로 수행 할 수 있기를 바랍니다. 그것은 사실이 아닙니다. 그것은 사람들이 공유 할 수 있기를 바라는 일종의 지혜입니다. Larrabee의 링크는 흠이 없습니다.
Will

그가 라라 비에 대해 이야기하고있는 것 같지는 않지만, 스탠포드 녀석은 2010 년 2 년 후 같은 연설을 했습니다 (여기에서 볼 수 있습니다 ). 그의 그림에서 while 루프를 고려할 때 계산을 더 빨리 "종료"하는 픽셀이 어떤 성능을 구성하는지 이해하지 못했습니다. CUDA에서 스레드는 장벽을 기다립니다. 유추하여, 셰이더 스레드는 어떻게됩니까?
teodron

@teodron 예, CUDA에 대한 이해를 가지고 GPU에 적용했습니다. 나는 그들이 멈춰 있다고 확신하지만, 누군가를 알아볼 수있는 사람을 원합니다. 어쨌든, 여기에 관련된 것이 있습니다 williamedwardscoder.tumblr.com/post/26628848007/rod-marching
Will

답변:


8

GDC 2012에서 GPU 거리 필드 레이 마칭 (및 기타 주제)에 대한 좋은 이야기가있었습니다. http://directtovideo.wordpress.com/2012/03/15/get-my-slides-from-gdc2012/

성능면에서 최신 (DX11 급) 그래픽 카드는 잠금 단계에서 32 (NVIDIA) 또는 64 (AMD) "스레드"를 실행하는 SIMD 장치에서 셰이더를 실행합니다. 이 그룹은 날실 또는 파면으로 다양하게 알려져 있습니다. 픽셀 셰이더의 경우 각 스레드는 하나의 픽셀과 동일하므로 SIMD 장치가 8x4 (NVIDIA) 또는 8x8 (AMD) 픽셀 블록과 같은 것을 함께 처리 할 것으로 예상됩니다. 분기 및 흐름 제어는 파면마다 수행되므로 파면의 모든 스레드는 해당 파면 내의 가장 깊은 개별 픽셀 수만큼 반복되어야합니다. SIMD 레인 마스크는 이미 완료된 픽셀의 실행을 해제하지만 여전히 전체 웨이브 프런트의 흐름 제어와 함께 자동으로 진행해야합니다. 물론 이것은 분기가 일관된 경우 시스템이 훨씬 더 효율적이며

필자의 경험에 따르면 웨이브 프론트 브랜치의 모든 스레드가 동일한 방식으로도 분기 오버 헤드가 여전히 높습니다. 일부 경우 오버 헤드를 일부 상각하기 위해 루프를 풀면 성능이 향상되는 것을 보았습니다. 그러나 각 루프 반복에서 수행하는 작업량에 따라 다릅니다. 루프 바디에 충분한 "재료"가 있으면 롤링이 승리하지 않습니다.



0

동적 브랜칭과 관련하여 하나의 추가 참고 사항 (명확하지만 여전히 일부 사람들에게 주목할 가치가 있음) : 언롤 루프의 성능에 심각한 영향을 줄 수 있습니다 (일정하지 않은 반복 횟수가 있으면 루프를 풀 수 없습니다) .


-4

int s = 0;

이제 for (int k = 1; k <= n; k ++) {s + = k;}는 s = n * (n + 1) / 2와 같습니다.

그래서 일반적으로 사실이 아닙니다 : D


1
여기에 전달하려는 내용이나 질문과 관련된 내용을 확실히 모르는 사람이 많기 때문에 많은 의견을 낼 수 있습니다.
doppelgreener
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.