스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Metal 셰이더를 위한 성능 모범 사례 알아보기
Apple GPU의 최신 개선 사항을 활용하여 Metal 셰이더 성능을 개선하는 방법을 알아보세요. 함수 상수를 구성하여 셰이더의 실행 시간을 줄이고, 함수 그룹으로 컴파일러 최적화를 향상해 보세요. 셰이더의 실행을 향상하고 리소스를 병렬로 사용하는 역량을 개선하여 런타임을 줄이는 방법을 학습해 보세요. Apple Family 9 GPU의 기능을 자세히 알아보고 레이 트레이싱에 하드웨어 가속을 활용해 보세요.
리소스
관련 비디오
Tech Talks
WWDC23
WWDC20
-
다운로드
안녕하세요, 제 이름은 Srividya Karumuri입니다 저는 Apple의 GPU 컴파일러 엔지니어입니다 본 세션에서는 Metal 셰이더의 성능을 향상할 수 있는 팁을 공유하겠습니다
새로운 Apple Family 9 GPU가 M3 및 A17 Pro에서 선보이고 있는 놀라운 신기능은 애플리케이션에 적용할 수 있습니다 Apple Family 9 GPU를 위한 권장 사항과 함께 전 세대의 Apple GPU에 적용할 수 있는 조언과 팁을 공유해 드리겠습니다
Metal 셰이딩 언어로 셰이더 런타임을 줄여 셰이더 성능을 향상하고 셰이더의 리소스 활용을 개선하여 병렬성을 높이고
Apple Family 9 GPU 내 레이 트레이싱 가속 하드웨어의 성능을 극대화할 수 있습니다
Metal에는 셰이더의 런타임을 최소화하는 기능이 있습니다 함수 상수는 셰이더를 효율적으로 특수화하며 함수 그룹은 셰이더 최적화를 위해 간접 함수 호출을 사용합니다
Metal의 함수 상수 기능은 셰이더를 효율적으로 특수화하고 런타임에 도달할 수 없는 코드를 제거합니다 예를 들어 대부분 우버 셰이더는 함수 상수를 활용합니다
우버 셰이더는 대개 복잡합니다 왜냐하면 3D 애플리케이션에서 서로 다른 머티리얼 유형을 렌더링하는 등, 런타임에 수많은 가능성을 처리할 수 있기 때문입니다
때때로 개발자는 버퍼에서 머티리얼 매개변수를 읽어 들이는 우버 셰이더를 만듭니다 그러면 머티리얼 셰이더가 버퍼의 콘텐츠를 기반으로 런타임에 다른 제어 부분을 선택합니다
이 방식을 사용하면 재컴파일 없이 셰이더가 새 머티리얼 효과를 렌더링합니다 오직 버퍼의 매개변수만 변경되기 때문입니다
예를 들어 파이프라인의 이 우버 셰이더는 광택이 나는 머티리얼을 렌더링합니다 드로우 명령에 있는 Metal 버퍼에 is_glossy: true로 설정된 매개변수가 있기 때문입니다 버퍼의 is_glossy 매개변수가 false로 설정되면 같은 셰이더가 매트한 머티리얼을 렌더링하게 됩니다
렌더링 파이프라인은 두 머티리얼 효과에 동일합니다 동작을 변경하는 요소는 버퍼의 콘텐츠이기 때문입니다
이 방법은 반응성이 뛰어나고 개발에 유용하지만 셰이더가 여러 가능성을 처리할 수 있어야 하고 추가 버퍼에서 읽어 들어야 하므로 앱의 성능에 영향을 줄 수 있습니다 셰이더를 특수화하는 또 다른 방법은 런타임 대신 컴파일 타임에 하는 것입니다 전처리기 매크로로 셰이더 배리언트를 오프라인으로 빌드하면 됩니다
화면의 우버 셰이더는 매크로로 특수화한 것입니다
특수화된 셰이더마다 자체 렌더링 파이프라인이 있고 특정 머티리얼 효과를 렌더링하는 데 필요한 코드만 있습니다
이 방법에서는 모든 가능한 배리언트 조합을 오프라인으로 컴파일해야 합니다 예를 들어 광택 배리언트는 is_glossy 및 use_shadows 매크로를 제외한 나머지 매크로를 비활성화하여 조합할 수 있습니다
마찬가지로 매트 함수 배리언트는 use_shadows 및 has_reflections 매크로를 조합합니다
광택 반사 배리언트는 is_glossy 및 has_reflections 매크로를 활성화합니다
매크로로 우버 셰이더를 구현하려면 대량의 배리언트를 컴파일해야 합니다 하나의 배리언트를 가능한 매크로 조합마다 컴파일해야죠 앱에서 사용하지 않는 조합도 있을 것입니다
미리 오프라인에서 컴파일하더라도 각 배리언트가 더해지면 Metal 라이브러리의 규모가 크게 증가할 수 있습니다 또한 각 셰이더 배리언트를 Metal 소스에서 컴파일해야 하므로 컴파일 타임이 늘어날 수 있습니다
함수 상수로 셰이더를 특수화하는 또 다른 방법이 있습니다 매크로를 사용하는 방법에 비해 컴파일 타임과 Metal 라이브러리 규모를 모두 줄일 수 있습니다 함수 상수를 사용하면 우버 셰이더를 소스에서 중간 Metal 함수로 한 번 컴파일합니다 해당 함수에서는 앱에서 필요한 배리언트를 정의한 함수 상수에 기반하여 한 번만 생성합니다
함수 상수를 사용하면 여러 특수화된 배리언트를 필요에 따라 즉석에서 생성하고 나머지 모든 가능성에 중간 Metal 함수를 재사용할 수 있습니다
이 방법은 필요한 셰이더 배리언트와 파이프라인만 렌더링하므로, 작업 시간과 저장 공간을 절약합니다
Metal 함수 코드에서 함수 상수를 선언하고 Metal 함수에 그 값을 정의하여 특수화된 배리언트를 생성할 수 있습니다
또한 함수 상수를 사용하여 상수 주소 공간에 선언하는 프로그램 범위 변수를 초기화할 수 있습니다
Metal 버퍼에서 값을 읽어 들이는 대신 함수 상수를 사용하여 셰이더의 다양한 코드 부분을 활성화할 수 있습니다
Metal은 함수 상수를 사용하여 도달 불가능한 코드 부분을 삭제하는 등 셰이더의 특수화 배리언트와
기타 최적화 항목을 컴파일하면서 이를 상수 불리언으로 폴드합니다
그러면 사용하지 않는 제어 흐름이 제거됩니다
함수 상수로 셰이더를 특수화하면 더 이상 버퍼로부터 머티리얼 매개변수를 쿼리하지 않아도 됩니다 이 방법은 제어 흐름을 단순화하고 사용하지 않는 코드 부분을 제거하여 셰이더 런타임을 줄입니다
‘Metal로 GPU 렌더링 최적화하기’에서 런타임에 함수 상수 값을 설정하는 법을 자세히 알아보세요 같은 비디오에서 동기식 컴파일을 통해 런타임 컴파일 오버헤드를 완화하는 방법도 확인할 수 있습니다
간접 함수 호출에 함수 그룹의 속성을 추가하여 셰이더 런타임을 줄이는 방법도 있습니다
간접 함수는 셰이더가 함수를 호출할 때 이름으로 직접 호출하지 않는 대신 함수 포인터나 가시적인 함수 테이블을 사용합니다
셰이더는 정적, 동적 연결을 통해 간접 함수를 호출합니다 간접 함수 호출은 코드를 확장 가능하게 하므로 앱을 위한 옵션을 유연하게 선택할 수 있습니다 그러나 간접 함수 호출은 Metal이 셰이더를 완전히 최적화하는 데 방해가 될 수 있습니다 특히 호출 위치 주변에서 그러합니다
정적으로 연결된 함수의 경우 Metal 함수 그룹 기능을 사용하여 Metal이 간접 함수 호출을 통해 셰이더를 최적화하도록 할 수 있습니다
이 셰이더는 세 개의 간접 함수를 호출하는데 조명과 머티리얼을 위한 함수 포인터 호출이 포함되어 있습니다 Metal은 이 함수 포인터의 호출 사이트를 전반적으로 최적화할 수 없습니다 셰이더가 어떤 함수를 호출하는지 알 수 없기 때문입니다 하지만 함수 포인터는 정해진 함수 그룹에서 하나의 함수만 가리킨다는 점을 이용해, 함수 그룹의 속성을 활용할 수 있습니다 예를 들어, 셰이더는 셰이더 파이프라인 상태에 있는 연결된 함수만 호출할 수 있는데
조명 함수는 그 중에서 area, spot, sphere 함수만 호출할 수 있습니다 이 경우 이것들을 조명 함수 그룹으로 그룹화할 수 있습니다 또한 머티리얼 함수 포인터가 wood, glass, metal 함수만 호출한다면 이를 머티리얼 함수 그룹으로 그룹화할 수 있습니다
Metal에서 간접 호출을 최적화할 수 있게 호출 위치에 함수 그룹의 속성을 추가할 수 있습니다
함수 그룹을 정의하려면 연결된 함수 그룹의 속성에 딕셔너리를 할당합니다 각 딕셔너리 엔트리는 그룹의 이름으로 된 문자열 키이며, 값은 해당 그룹에 속하는 함수 영역입니다 이 방법은 정적으로 연결한 함수에만 도움이 되며, 바이너리 라이브러리로 컴파일한 함수는 해당되지 않습니다
화면의 두 비디오에서 Metal 함수 포인터와 다양한 컴파일 작업 흐름에 대해 자세히 알아보세요
요약하자면, 셰이더의 런타임을 줄이는 두 가지 방법은 함수 상수를 사용하여 셰이더의 특수화된 배리언트를 효율적으로 생성하고 함수 그룹으로 간접 함수를 호출하는 셰이더를 최적화하는 것입니다
셰이더 런타임을 줄일 수 있는 Metal 기능을 살펴보았으니 이제 리소스 활용 개선으로 병렬성을 향상하는 방법을 알아보겠습니다
스레드 점유율의 향상은 셰이더 실행에서 지연 숨김을 줄이는 데 매우 중요합니다
스레드 점유율은 레지스터나 메모리 등 사용 가능한 리소스의 용량에 따라 달라집니다
따라서 셰이더의 데이터를 최적화하여 사용하면 스레드 점유율을 높일 수 있습니다
Apple Family 9 GPU는 점유율을 관리하는 새로운 개선 사항이 있습니다 자세한 내용은 ‘M3 및 A17 Pro의 GPU 개선 사항 알아보기’에서 확인하세요
낮은 스레드 점유율로 인한 병목 현상을 분류하는 방법을 알아보려면 ‘M3 및 A17 Pro를 위한 새로운 Metal 도구 살펴보기’를 시청해 보세요
메모리 객체의 주소 공간과 ALU 작업에 사용되는 데이터 유형은 리소스 활용에 영향을 줄 수 있습니다
메모리 객체에 적합한 주소 공간을 선택하는 것은 메모리 활용 개선과 스레드 점유율 향상에 중요합니다
Metal 셰이딩 언어에서 주소 공간은 다양한 액세스 패턴을 지원하고
할당될 메모리 객체가 있는 메모리 영역을 지정하도록 설계되었습니다
올바른 주소 공간을 선택하면 셰이더 성능에 직접적인 영향을 줍니다 상수, 기기, 스레드 그룹 주소 공간에 주목합니다 상수 주소 공간을 사용하면 읽기 전용 메모리 객체를 생성할 수 있습니다
이러한 액세스는 모든 스레드 소프트웨어 디스패치 또는 드로우에서 일정한 데이터에 최적화됩니다
객체의 크기가 고정되어 있으며 다른 스레드에서 해당 객체를 여러 번 읽는 경우 상수 주소 공간에 객체를 생성합니다
기기 주소 공간에는 읽기/쓰기 버퍼를 생성할 수 있습니다 스레드마다 액세스하는 데이터가 다르거나 버퍼 크기가 고정되지 않은 경우 기기 주소 공간에 이러한 버퍼를 생성할 수 있습니다
‘Apple Silicon Mac에서 Metal 성능 최적화하기’에서 상수 및 기기 주소 공간에 관한 권장 사항과 예시를 확인해 보세요
스레드 그룹 주소 공간에도 읽기/쓰기 메모리 객체를 생성할 수 있습니다 스레드 그룹의 스레드는 스레드 그룹 메모리의 데이터를 공유하여 함께 작동할 수 있습니다
이러한 스레드는 대부분 더 빠릅니다
일부 사용 사례에서는 스레드 그룹 메모리가 기기 또는 상수 버퍼의 소프트웨어 관리 캐시로 사용됩니다 예를 들어 기기 메모리 블록을 작업에 함께 사용하기 위해 스레드 그룹 메모리에 복사합니다 어떤 경우에는 더 빠를 수도 있습니다
Apple Family 9 GPU의 셰이더 코드 메모리가 선사하는 새로운 개선 사항 덕분에 스레드 그룹 메모리의 사용 시점에 대한 균형점이 이전 GPU와는 다를 수 있습니다
셰이더에서 스레드 그룹 메모리가 주로 기기의 소프트웨어 관리 캐시 또는 상수 버퍼로 사용되는 경우, 스레드 그룹 메모리로 복사하는 대신 해당 버퍼에서 직접 읽어올 때 성능이 더 좋을 수 있습니다
Apple Family 9 GPU의 동적 셰이더 코어 메모리와 유연한 온칩 메모리 기능 덕분에 스레드 그룹 기기 상수 메모리 유형은 동일한 캐시 계층 구조를 사용합니다 따라서 작업 세트 크기가 캐시에 맞으면 버퍼 및 스레드 그룹 메모리 액세스 모두 비슷한 성능 특성을 가질 수 있습니다 이 경우 스레드 그룹 및 기기 또는 상수 주소 공간에 메모리 복사본을 만드는 대신 셰이더가 기기 또는 상수 버퍼와 함께 작동하여 스레드 그룹 메모리에 복사하는 데 걸리는 지연 시간을 방지합니다
추가적으로 기기 또는 상수 버퍼에만 데이터를 유지하는 게 유리한지 아닌지는 Xcode의 Metal 디버거로 워크로드를 프로파일링하여 평가할 수 있습니다
주소 기반 선택과 유사하게 데이터 유형도 성능에 영향을 줄 수 있습니다 예를 들어, 16비트 데이터 유형은 레지스터와 메모리 공간을 줄이는 데 도움이 될 수 있습니다
가능한 경우 float, int 대신 half, short 등의 16비트 데이터 유형을 사용하면 성능이 향상됩니다 half-float 전환 등 유형 간 전환은 자유롭게 할 수 있습니다 Bfloat는 float를 16비트로 줄인 버전으로
머신 러닝 앱을 가속하는 데 적합합니다
Bfloat는 더 낮은 정밀도로 광범위한 값을 허용합니다
Bfloat 데이터 유형은 Metal 3.1부터 지원되었습니다 앱의 정밀도 요구 사항이 Bfloat 지원 버전과 맞는다면 이 데이터 유형을 사용하는 것이 매우 권장됩니다
32비트 데이터 유형 대신 16비트 유형을 사용하면 셰이더가 더 적은 수의 레지스터를 사용하게 됩니다 이러한 데이터가 메모리에 있으면 메모리 사용량 절감과 대역폭 향상에도 도움이 됩니다 결과적으로 스레드 점유율이 개선될 수 있습니다 16비트 데이터 유형을 사용하면 에너지 효율도 향상됩니다
절반의 정밀도로 평가해야 하는 표현식을 작성할 때는 모든 리터럴에 ‘h’ 접미사를 사용해야 합니다 그렇지 않으면 전체 표현식이 float 정밀도로 평가되어 더 작은 유형을 사용하는 이점이 사라집니다
어떤 셰이더에서는 half 유형으로 명령어를 조합해 더 좋은 결과를 얻을 수 있습니다 예를 들어 float, half int 유형의 명령어를 조합하는 것입니다 이를 통해 Apple Family 9 GPU ALU 파이프라인의 활용도와 명령어 처리량이 향상될 수 있습니다
요약하면, 메모리 사용 패턴에 따라 적절한 주소 공간을 선택하면 리소스 활용도를 높일 수 있습니다 16비트 데이터 유형을 선택하면 레지스터 및 메모리 사용량을 줄이는 데 유용하며, 어떤 경우에는 Apple Family 9 GPU에서 ALU 병렬성을 더 잘 활용할 수 있습니다 레이 트레이싱 셰이더의 경우에도 셰이더 실행 시간을 줄이고 리소스 활용도를 높이는 게 성능 향상에 중요합니다
Metal 레이 트레이싱으로 렌더링하는 첫 단계는 효율적인 충돌(Intersection) 처리를 위해 장면 지오메트리를 정의하고 가속 스트럭처를 빌드하는 것입니다
충돌은 광선을 생성하는 GPU 함수에서 수행됩니다 이 GPU 함수는 인터섹터 객체를 만들어 충돌을 수행합니다 충돌에서 반환된 결과는 픽셀을 셰이딩하거나 추가 처리하는 데 필요한 모든 정보를 담고 있습니다
이 프로세스의 인터섹터 구성 요소는 Apple Family 9 GPU에서 하드웨어 가속됩니다
하드웨어 인터섹터는 가속 스트럭처를 순회하고 충돌 함수를 호출하며 충돌 결과를 기준으로 순회 상태를 업데이트하는 역할을 합니다
인터섹터는 Metal 레이 트레이싱의 핵심 API입니다 충돌 함수, 광선 페이로드, 충돌 태그, 충돌을 최적의 방식으로 사용하면 레이 트레이싱 성능을 향상할 수 있습니다
사용자 설정 충돌 함수는 광선이 표면에 닿는 방식을 정의하는 강력한 방법이지만 필요한 경우에만 사용하는 것이 좋습니다
사용자 설정 충돌 함수는 알파 테스트와 같은 기능을 구현하는 데 중요합니다 알파 테스트는 화면 이미지의 체인과 나뭇잎 등 장면에 지오메트리 세부 정보를 추가하는 데 사용됩니다 사용자 설정 충돌 함수를 사용하여 알파 테스트를 구현할 수 있습니다
사용자 설정 충돌 함수의 내부 논리는 광선이 가속 스트럭처를 순회할 때 충돌을 허용하거나 거부합니다
이 경우 사용자 설정 충돌 함수의 논리는 첫 번째 충돌을 거부하지만
두 번재 충돌은 불투명 표면을 대상으로 일어났기 때문에 허용합니다
사용자 설정 충돌 함수는 셰이더 호출에서 추가 논리를 실행할 수 있도록 합니다 필요한 경우에만 사용하세요 불투명 삼각 인터섹터가 가장 빠른 방법입니다
사용자 설정 충돌 함수가 필요한 경우 하드웨어는 충돌 함수에 따라 정렬 및 그룹화합니다 따라서 충돌 함수가 많으면 일치 항목과 그룹을 찾는 것이 어려워지므로
충돌 함수가 중복되지 않도록 최적의 그룹화를 돕는 게 좋습니다
또한 Metal 충돌 함수 테이블 인덱싱 메커니즘을 활용하여 함수당 하나의 엔트리가 있는 간단한 테이블을 만드세요
하드웨어 충돌은 충돌을 테스트하기 위해 여러 광선에 SIMD 그룹을 생성하고 각 광선을 여러 프리미티브에 대해 병렬로 테스트합니다
사용자 설정 충돌 함수는 병렬 실행되므로, 함수가 의도하지 않은 결과가 나오는 작업을 수행하는 경우 이를 직렬화해야 합니다 이는 페이로드나 기타 기기 메모리에서 발생하는 메모리 쓰기 작업을 포함합니다 간접 함수 호출 등 분기(Divergence)를 유발하는 모든 작업에서도 충돌 함수 실행의 병렬성이 감소합니다
이러한 작업 단계에 올 때까지 병렬성을 최대한 유지하려면, 충돌 함수에서 해당 작업을 가능한 한 나중에 하는 것이 좋습니다
이 예제에서는 광선 페이로드가 먼저 업데이트된 다음 페이로드와 관련 없는 작업 업데이트가 수행됩니다
이렇게 하면 모든 코드가 페이로드 업데이트 후 순차적으로 실행됩니다 대신 충돌 함수를 수정하여 페이로드 업데이트와 관련 없는 모든 작업을 먼저 처리한 후에 페이로드를 업데이트합니다 이렇게 하면 충돌 함수 병렬성을 최대화할 수 있습니다
하드웨어 인터섹터 모델로 돌아가서 이 순서도는 프로세스를 설명하고 있지만 한 가지 중요한 요소를 간과하고 있습니다
임시 레이 트레이싱 공간은 충돌 처리 중 순회 상태를 저장하고 충돌을 호출한 GPU 함수에 결과를 반환하는 데 사용됩니다
인터섹터 API는 각 광선의 페이로드를 지원합니다 페이로드 구조가 클수록 레이 트레이싱 성능에 더 많은 영향을 줍니다
광선 페이로드의 경우 필요한 대부분의 데이터가 충돌 결과에 있을 것이며 따라서 광선 페이로드를 사용하지 않는 것이 좋습니다 페이로드가 필요한 경우 글로벌 우버 페이로드 구조는 피하세요 대신 각 충돌 호출에 대한 구조를 특수화하세요
압축된 데이터 유형을 사용하여 구조의 크기를 최소화하고 필요하지 않은 필드를 모두 제거하세요 광선 페이로드 사용을 최적화하면 더 많은 광선을 처리할 수 있습니다
충돌 위치, 히트를 표시하는 플래그 색상 정보를 담은 기본 페이로드를 예로 들어 보겠습니다 메모리상의 필드 레이아웃은 이렇게 되어 있을 것입니다
위치 멤버는 시작 부분에 있고 히트 플래그의 크기와 정렬로 인해 16바이트로 시작하지만
RGB 멤버의 바이트 오프셋은 32이므로 전체 구조 크기는 48바이트입니다
float3 값을 압축된 값으로 변경하면 정렬에서 낭비되는 공간이 줄어듭니다 히트 플래그는 Metal 레이 트레이싱 API를 사용할 때 필요하지 않으므로 제거합니다 충돌 결과에서 충돌 유형만 확인하면 됩니다 특히 그림자, 오클루전과 같은 시각 광선을 처리할 때 더 용이하고 효과적인 방법입니다 마찬가지로 위치는 결과에서 얻은 광선의 원점, 방향 충돌 거리를 바탕으로 계산할 수 있습니다
그 다음, 크기를 더 줄이기 위해 충돌 함수에서 Metal 셰이딩 언어의 packing 메서드를 사용하여 RGB 색상을 4바이트로 압축합니다
이 예제에서 광선 데이터 페이로드 구조는 48바이트 크기로 시작하여 4바이트로 축소되었습니다 이러한 방법을 사용하면 광선 페이로드를 최적화하고 레이 트레이싱 성능을 향상시킬 수 있습니다
광선 페이로드와 마찬가지로 충돌 태그도 비슷하게 레이 트레이싱 성능에 영향을 줍니다
임시 레이 트레이싱 공간이 사용되는 또 다른 이유는 인터섹터의 충돌 태그입니다 이러한 태그는 순회에서 추적해야 할 추가 상태입니다
이 선언에 있는 world_space_data 태그는 각 광선에 대해 객체에서 월드 월드에서 객체 매트릭스가 저장되어야 함을 의미합니다 이것 역시 임시 레이 트레이싱 공간 사용량을 차지하며 충돌 호출 중 점유율에 영향을 줍니다
태그와 관련된 또 다른 중요한 점은 인터섹터 및 태그가 호출하는 충돌 함수와 일치해야 한다는 것입니다
충돌 쿼리 API가 레이 트레이싱 성능에 주는 영향을 고려하면, 충돌 쿼리 API보다 인터섹터가 더 좋은 방법입니다
하드웨어 인터섹터 모델을 살펴보면 셰이딩 언어의 인터섹터에 매우 적합합니다
충돌 쿼리는 사용자 설정 충돌 함수를 사용하지 않는 객체를 정의합니다 충돌 코드는 원본 GPU 함수에서 실행되며 하드웨어 충돌은 순회를 계속하기 전에 코드가 완료될 때까지 기다려야 합니다
충돌 쿼리를 사용하기로 선택한 경우 하드웨어에는 정렬할 사용자 설정 충돌 함수가 없으며 실행을 그룹화할 수 없습니다
또한 GPU 함수로 돌아가는 데 더 많은 임시 레이 트레이싱 메모리가 필요합니다
충돌 쿼리는 광선 충돌이 다른 셰이딩 언어의 이식성을 지원하도록 하기 위한 대안 모델입니다 인터섹터는 하드웨어 구현과 정렬되므로 충돌 쿼리 대신 인터섹터를 우선 사용하세요
충돌 쿼리를 사용해야 하는 경우 가능한 한 적은 수의 쿼리 객체를 사용하세요 여러 충돌 쿼리가 필요한 경우 쿼리 객체를 재사용하되 속성을 변경하세요 그러면 임시 레이 트레이싱 공간을 재사용할 수 있습니다 예제의 충돌 쿼리 객체 IQ1처럼 작업을 어느 정도 한 이후에 불투명도를 opaque로 설정하여 레이 트레이싱을 더 하려는 경우 새 충돌 쿼리 객체를 생성하는 대신 간단하게 기존 충돌 쿼리 객체에서 불투명도를 opaque로 재설정한 충돌 매개변수를 사용하세요
그러면 임시 레이 트레이싱 메모리를 재사용할 수 있습니다
여러 충돌 쿼리를 사용할 때 두 쿼리 사이에서 전환하거나 순회가 겹치지 않도록 하세요 이렇게 하면 진행 중인 하드웨어 순회 사이에 코스트가 높은 전환을 방지할 수 있습니다
예를 들어 레이 트레이싱 작업에서 IQ1에서 IQ2로 전환했다가 다시 IQ1로 돌아가는 대신 IQ1에서 필요한 레이 트레이싱 작업을 완료한 후 IQ2로 전환하세요 레이 트레이싱 모범 사례를 요약하면 필요한 경우에만 사용자 설정 충돌 함수를 사용하세요
광선 페이로드를 최적화하세요
충돌 태그의 수를 최소화하세요
충돌 쿼리보다 인터섹터를 우선 사용하세요
Metal을 사용한 레이 트레이싱에 대한 자세한 정보는 ‘Metal 레이 트레이싱 가이드’에서 확인하세요 Xcode에 있는 Metal 디버거의 새로운 레이 트레이싱 카운터의 사용법을 알아보려면 ‘M3 및 A17 Pro를 위한 새로운 Metal 도구 살펴보기’를 시청하세요
요약하자면 Metal 셰이더의 성능을 향상하기 위해 함수 상수, 함수 그룹 등의 Metal 기능을 사용하여 셰이더 실행 시간을 줄일 수 있습니다 이러한 기능을 사용하면 Metal의 최적화 기회가 확대되며, 병렬성을 높이는 탁월한 리소스 활용을 통해 스레드 점유율을 향상할 수 있습니다
충돌 함수, 광선 페이로드 충돌 태그, 인터섹터의 모범 사례를 적용하여 하드웨어 가속 레이 트레이싱을 최대한 활용하세요
시청해 주셔서 감사합니다
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.