OpenCL에서 재귀가 금지 된 이유는 무엇입니까?


19

광선 추적 이미지의 렌더링을 가속화하기 위해 OpenCL을 사용하고 싶지만 Wikipedia 페이지 에서 재귀가 Open CL에서 금지되어 있다고 주장합니다. 이것이 사실입니까? 레이트 레이싱시 재귀를 광범위하게 사용함에 따라 속도 향상을 위해 상당한 양의 재 설계가 필요합니다. 재귀를 막는 기본 제한은 무엇입니까? 그 주위에 어떤 방법이 있습니까?


2
GPU는 다른 방식으로 작동합니다. (일부 아키텍처)에는 전역 "프로그램 스택"이라는 개념이 없으므로 재귀 함수 호출은 불가능합니다. OpenCL은 아마도 가장 낮은 공통 분모를 채택하므로 GPU에서 완전히 이식 가능한 상태를 유지할 수 없습니다. : 최근 CUDA 하드웨어는 어떤 점에서 재귀에 대한 지원을 도입 것으로 보인다 stackoverflow.com/q/3644809/1198654
glampert

답변:


27

기본적으로 모든 GPU가 함수 호출을 지원할 수있는 것은 아니며, 가능하더라도 함수 호출이 매우 느리거나 스택 깊이가 매우 작은 등의 제한이있을 수 있습니다.

셰이더 코드와 GPU 계산 코드는 모든 곳에서 함수 호출을하는 것처럼 보이지만 정상적인 상황에서는 컴파일러가 100 % 인라인합니다. GPU가 실행하는 머신 코드에는 분기와 루프가 포함되어 있지만 함수 호출은 없습니다. 그러나 재귀 함수 호출은 명백한 이유로 인라인 될 수 없습니다. (일부 인수가 컴파일 타임 상수가 아닌 한, 컴파일러가 인수를 접고 전체 호출 트리를 인라인 할 수있는 방식으로)

진정한 함수 호출을 구현하려면 스택이 필요합니다. 대부분의 경우 셰이더 코드는 스택을 전혀 사용하지 않습니다. GPU에는 대용량 레지스터 파일이 있으며 모든 데이터를 레지스터에 항상 보관할 수 있습니다. (a) 한 번에 비행 할 수있는 모든 워프를 제공하기 위해 많은 스택 공간이 필요하고 (b) GPU 메모리 시스템이 많은 일괄 처리에 최적화되어 있기 때문에 스택 작업이 어렵습니다. 높은 처리량을 달성하기 위해 메모리 트랜잭션이 발생하지만 대기 시간이 발생하기 때문에 로컬 변수 저장 / 복원과 같은 스택 작업이 상당히 느릴 것입니다.

역사적으로 하드웨어 수준의 함수 호출은 컴파일러에서 모든 것을 인라인하는 것이 더 합리적이기 때문에 GPU에서 그다지 유용하지 않았습니다. 따라서 GPU 아키텍트는 빠르게 만드는 데 집중하지 않았습니다. 향후 하드웨어 수준의 효율적인 호출이 필요할 경우 엔지니어링의 모든 항목과 마찬가지로 다른 곳에서 비용이 발생할 수 있습니다.

레이트 레이싱과 관련하여 사람들이 일반적으로 이러한 종류의 작업을 처리하는 방법은 추적중인 광선 큐를 생성하는 것입니다. 되풀이하는 대신 대기열에 광선을 추가하고 높은 수준에서 모든 대기열이 비워 질 때까지 처리를 유지하는 루프가 있습니다. 그래도 클래식 재귀 레이트 레이서에서 시작하는 경우 렌더링 코드를 크게 재구성해야합니다. 자세한 내용은 Wavefront Path Tracing 입니다.


6
나는이 비밀 소스를 공유하는 것을 꺼려하지만, 고정 된 최대 바운스 수를 가지고이를 처리하기 위해 고정 된 크기의 스택 (및 고정 된 반복 횟수를 가진 루프)을 갖는 것은 매우 행운이 있습니다. 또한 (그리고 이것은 진짜 비밀 소스 이모입니다!) 나는 내 재료가 반사 또는 굴절이지만 둘 다 결코 가지지 않으므로 광선이 튀어 나올 때 갈라지지 않습니다. 이 모든 것의 최종 결과는 재귀 유형이 아닌 광선 추적 렌더링이지만 재귀가 아닌 고정 크기 반복을 통해 이루어집니다.
Alan Wolfe

꼬리 재귀처럼?
Tanmay Patil

꼬리 재귀 함수는 반복 함수로 변환 될 수 있으므로 꼬리 재귀를 수행하기 위해 스택이 필요하지 않습니다. OpenCL 컴파일러가이를 자동으로 수행하지 않습니까?
앤더슨 그린
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.