언리얼 렌더링 시스템 분석(12) - 모바일 특집 2부(GPU 아키텍처 및 메커니즘)
🌐 원문 링크: 剖析虚幻渲染体系(12)- 移动端专题Part 2(GPU架构和机制) (cnblogs.com/timlly)
📅 원문 발행일: 2021-11-12 | ✍️ 저자: Timlly (00 / )💡 시리즈 분류:
Hardware & Architecture| 국내 업계 표준 용어 감수 및 수식/도해 복원 적용 완료
이 기간 동안 저자는 최근 몇 년간 모바일 단말기에 관한 Siggraph와 GDC 논문을 연구했으며, Qualcomm, Arm, PowerVR 등 모바일 GPU 제조업체와 일부 모바일 장치 제조업체의 개발 가이드를 검토했습니다. 이 장에서는 모바일 단말기의 일반적인 전용 렌더링 기술을 요약합니다.
자세한 내용은 아래 참조 목록을 확인하세요.
12.4.1 타일 기반(지연) 렌더링
TBR의 전체 이름은 Tile-based Rendering이며, 이는 타일 기반 렌더링으로 번역됩니다. 렌더링을 가속화하고 대역폭과 에너지 소비를 줄이기 위해 현재 모바일 GPU 아키텍처에서 널리 사용되는 기술입니다.
TBDR의 정식 명칭은 Tile-based Deferred Rendering이며, 이는 TBR의 개선된 버전으로, 타일 기반 디퍼드 렌더링을 의미합니다. PowerVR의 GPU 칩에 처음 사용되었습니다. 가장 중요한 차이점은 Early-Z 테스트를 통과한 픽셀이 픽셀 셰이더를 즉시 실행하지 않고 픽셀이 속한 기본 요소를 먼저 표시한다는 것입니다. 타일이 모든 프리미티브(장면의 모든 객체)를 처리하면 타일에 표시된 모든 픽셀이 그려집니다. TBDR은 하드웨어 수준의 폐색 픽셀 제거를 달성하고 OverDraw를 줄이며 대역폭과 메모리 액세스를 줄입니다.
PowerVR의 TBDR은 렌더링을 시작하기 전에 전체 장면을 캡처하므로 가려진 픽셀이 픽셀 셰이더를 통과하기 전에 식별되고 선별될 수 있습니다. 각 타일은 래스터라이제이션되고 개별적으로 처리되므로 렌더링 크기가 작기 때문에 모든 데이터를 매우 빠른 타일 메모리에 보관할 수 있습니다.
TB(D)R에 해당하는 것은 PC용 IMR(Immediately Rendering) 모드입니다. IMR, TBR, TBDR 아키텍처의 비교 차트는 다음과 같습니다.

IMR, TBR, TBDR 아키텍처 동작 다이어그램. 빨간색 타원은 높은 대역폭을 나타내며 이로 인해 성능 병목 현상이 발생합니다.
IMR 모드 GPU의 경우 병렬 처리 논리가 무시되면 실행되는 의사 코드는 다음과 같습니다.
for draw in renderPass:
for primitive in draw:
for vertex in primitive:
execute_vertex_shader(vertex)
if primitive not culled:
for fragment in primitive:
execute_fragment_shader(fragment)IMR의 GPU 하드웨어 아키텍처는 다음과 같습니다.

하드웨어 데이터 흐름 및 메모리 상호 작용 다이어그램은 다음과 같습니다.

IMR 모드 GPU의 장점은 버텍스 셰이더 및 기타 지오메트리 관련 셰이더의 출력이 GPU 내의 온칩으로 유지될 수 있다는 것입니다. 이러한 셰이더의 출력은 파이프라인의 다음 단계에서 데이터를 사용할 준비가 될 때까지 FIFO 버퍼에 저장할 수 있으며, GPU는 매우 적은 외부 메모리 대역폭을 사용하여 중간 형상 결과를 저장하고 검색할 수 있습니다.
IMR 모드에서 GPU의 단점은 삼각형이 그리기 순서대로 처리되고 데이터 스트림의 모든 삼각형이 화면의 모든 부분을 덮을 수 있기 때문에 픽셀 음영이 화면 주위로 점프한다는 것입니다(아래 이미지). 활성 작업 세트가 전체 프레임 버퍼의 크기라는 의미입니다. 예를 들어, 픽셀당 32비트(BPP) 색상과 픽셀당 32비트 채우기 깊이/스텐실을 사용하고 총 30MB의 작업 세트를 제공하는 1440p 해상도의 장치를 생각해 보세요. 모두 칩에 저장하면 데이터 양이 너무 많아 DRAM 오프 칩에 저장해야 합니다.

IMR의 병렬 렌더링 다이어그램, 랜덤 액세스가 전체 화면에 퍼져 캐시 적중률이 크게 감소합니다.
고해상도 이미지를 처리할 때 각 픽셀에 대한 읽기-수정-쓰기 작업이 여러 번 있기 때문에 메모리에 부과되는 대역폭 부하가 매우 높을 수 있습니다. 최근에 액세스한 프레임 버퍼 부분을 GPU에 가깝게 유지하면 고대역폭 부하가 완화될 수 있습니다.
TB(D)R GPU는 IMR GPU와 다릅니다. 먼저 화면을 여러 고정 크기 영역으로 나눈 다음 음영 계산을 수행합니다. 다음은 TBR의 실행 의사코드입니다.
## Pass one
for draw in renderPass:
for primitive in draw:
for vertex in primitive:
execute_vertex_shader(vertex)
if primitive not culled:
append_tile_list(primitive)
## Pass two
for tile in renderPass:
for primitive in tile:
for fragment in primitive:
execute_fragment_shader(fragment)TB(D)R GPU의 하드웨어 아키텍처는 다음과 같습니다.

하드웨어 데이터 흐름 및 메모리 상호 작용 다이어그램은 다음과 같습니다.

TB(D)R의 장점은 Tile이 전체 프레임 버퍼의 작은 부분만 차지한다는 것입니다. 따라서 색상, 깊이 및 스텐실의 전체 작업 세트를 GPU 셰이더 코어에 긴밀하게 연결된 빠른 온칩 RAM에 저장할 수 있습니다. 깊이 테스트 및 투명 픽셀 혼합을 위해 GPU에 필요한 프레임 버퍼 데이터는 외부 메모리에 액세스하지 않고도 얻을 수 있으며, GPU가 범용 프레임 버퍼 작업에 필요한 외부 메모리 액세스 수를 줄여 픽셀 집약적인 콘텐츠의 에너지 효율성을 크게 향상시킵니다. 또한 대부분의 경우 일시적이며 셰이딩 프로세스 중에만 존재하면 되는 깊이 및 스텐실 버퍼가 있습니다. 첨부 파일을 저장할 필요가 없다고 GPU 드라이버에 명시적으로 지시하면 드라이버는 해당 첨부 파일을 주 메모리에 다시 쓰지 않습니다.
다음 그래픽 API는 드라이버에 첨부 파일을 삭제하도록 지시할 수 있습니다.
OpenGL ES 2.0: glDiscardFramebufferEXT
OpenGL ES 3.0: glInvalidateFramebuffer
Vulkan: 적절한 렌더 패스 storeOp
각 타일의 크기는 일반적으로 그다지 크지 않기 때문에 단일 타일 내의 데이터에 액세스할 때 GPU 컴퓨팅 장치의 근접성이 좋아 캐시 적중률을 향상시킬 수 있다는 점을 언급할 가치가 있습니다.
물론 공짜 점심은 없고, TB(D)R에도 단점은 있습니다. 예를 들어 GPU는 지오메트리 채널의 출력(각 꼭짓점 및 타일의 중간 상태에 대한 변경 데이터)을 메인 메모리에 저장해야 하며, 셰이딩 채널은 이 데이터를 읽습니다. 따라서 지오메트리와 관련된 추가 대역폭 비용과 프레임 버퍼 데이터를 위해 절약된 대역폭 사이에 균형을 맞춰야 합니다. 테셀레이션과 같은 일부 렌더링 작업은 TBR에 비해 불균형적으로 비용이 많이 든다는 점을 고려하는 것도 중요합니다. 테셀레이션과 같은 작업은 IMR 모드 아키텍처를 활용하도록 설계되었습니다. 폭발적인 기하 데이터가 메인 메모리에 다시 기록되는 대신 온칩 FIFO 버퍼 내에 버퍼링될 수 있기 때문입니다.
다음은 Qualcomm Adreno 시리즈 GPU를 사용하여 TB(D)R의 아키텍처, 실행 프로세스, 렌더링 기술 및 최적화 기술을 설명합니다.

TB(D)R의 렌더링은 IMR 모드와 다릅니다. 렌더링 프로세스는 Binning Pass, Rendering Pass, Resolve Pass의 세 단계로 나뉩니다.
Binning Pass 프로세스는 대략 다음과 같습니다.
- 각 Bin(타일이라고도 함)에 고정 크기를 설정하고(2의 N승, 길이와 너비는 일반적으로 동일하며 특정 크기는 16x16, 32x32, 64x64와 같이 GPU 제조업체에 따라 다름) 프레임 버퍼 크기에 따라 표시되는 데이터 흐름을 설정합니다.

기본 좌표를 변환합니다. 이 단계에서는 인덱스 및 버텍스 데이터를 처리합니다. 일부 GPU(예: Adreno)는 대역폭과 에너지 소비를 줄이기 위해 좌표를 처리하는 데 완전한 버텍스 셰이더가 아닌 특수하고 단순화된 셰이더를 사용합니다. 일반적으로 이 단계에서는 정점의 위치만 유효하며 다른 버텍스 데이터(텍스처 좌표, 노멀, 탄젠트, 버텍스 색상)는 무시됩니다.
모든 기본 요소를 탐색하고, 모든 기본 요소가 포함하는 블록을 표시하고, 포함된 블록 데이터 스트림에 가시성 데이터를 씁니다.
가시성 데이터 스트림을 시스템 비디오 메모리에 다시 씁니다.

Binning 단계의 동작 다이어그램은 다음과 같습니다.

렌더링 패스 프로세스는 대략 다음과 같습니다.
렌더링 패스를 초기화합니다.
모든 청크를 반복하고 각 청크에 대해 다음 작업을 수행합니다.
청크된 가시성 데이터 흐름을 사용하여 그리기 호출을 실행합니다.
프리미티브를 래스터라이제이션합니다.
픽셀 작업(픽셀 셰이더, 깊이 스텐실 테스트, 알파 테스트, 블렌딩).
픽셀 데이터(색상, 깊이, 템플릿 등)를 타일형 칩(온칩 메모리, GMEM, 타일형 메모리라고도 함)의 버퍼에 씁니다.
렌더링 단계의 작업 다이어그램은 다음과 같습니다.

GPU에 타일 처리 장치가 여러 개 있는 경우 여러 타일을 동시에 처리할 수 있으며 타일 처리 장치는 서로 독립적입니다.

Resolve Pass 단계 프로세스는 다음과 같습니다.
- MSAA가 켜져 있으면 GMEM(평균값)에서 색상, 깊이 및 기타 데이터를 분석합니다. 후속 단계에서 GMEM이 시스템 메모리로 전송하는 총 데이터 양을 줄일 수 있습니다.

타일의 모든 픽셀 데이터(색상, 깊이, 템플릿 등)를 시스템 비디오 메모리에 씁니다.
프레임 버퍼의 마지막 블록이 아니면 다음 블록으로 계속 진행합니다.
프레임 버퍼의 마지막 블록인 경우 버퍼와 상호 작용하여 다음 프레임의 Binning Pass를 실행합니다.
구문 분석 단계의 작업 다이어그램은 다음과 같습니다(타일의 픽셀에는 앨리어싱이 포함되어 있으며 아래의 큰 그림은 MSAA 안티 앨리어싱이 구문 분석된 후의 픽셀입니다).

비닝 패스(Binning Pass)와 렌더링 패스(Rendering Pass)는 일반적으로 프레임 단위로 처리됩니다. 즉, 렌더링 패스는 비닝 패스(Binning Pass)보다 한 프레임 지연되어 지연을 줄이고 처리량을 향상하며 렌더링 효율성을 향상시킵니다.
TB(D)R GPU 아키텍처를 기반으로 한 많은 최적화 및 기술이 있으며 이에 대해서는 나중에 다루겠습니다.
12.4.2 계층적 타일링
계층적 타일링은 계층적 차단으로 번역됩니다. Arm Midgard 시리즈 칩에 사용된 최초의 차단 기술입니다. 이름에서 알 수 있듯이 레이어링을 기반으로 차단을 구현합니다.
이 경우 Hierarchical Tiling을 사용하면 Midgard는 타일 복잡도가 원하는 크기에 도달할 때까지(또는 최소 타일 복잡도에 도달할 때까지) 타일을 더 세분화하는 아이디어(계층 구조 아래, 아래 이미지 참조)를 기반으로 다양한 타일 크기를 사용할 수 있습니다. 이 기술을 통해 Midgard는 필요한 경우에만 작은 타일을 사용하고 덜 복잡한 장면에서 더 큰 타일을 사용하여 리소스를 절약할 수 있습니다.

보다 구체적으로 Arm은 일반적으로 다양한 수준의 저장소를 다음 크기로 설정합니다.
계층 수준 0은 16x16 픽셀로 설정됩니다.
계층 수준 1은 32x32 픽셀로 설정됩니다.
계층 수준 2는 64x64 픽셀로 설정됩니다.
계층 수준 3은 128x128 픽셀로 설정됩니다.
-......

시스템의 목표는 각 프리미티브에 포함된 블록을 찾고 블록의 구조 정보를 업데이트하는 것입니다.
위 그림의 회색 삼각형과 같이 작은 영역의 기본 요소인 경우 더 적은 수의 블록에 영향을 미치므로 낮은 수준의 블록을 사용하여 읽기 대역폭을 절약합니다.
넓은 영역의 기본 요소(예: 위 그림의 파란색 삼각형)인 경우 더 많은 블록에 영향을 미치므로 상위 수준 블록을 사용하여 쓰기 대역폭을 절약합니다.
복잡한 그래프 프리미티브의 경우 GPU는 어떤 분포가 가장 좋은지 자동으로 결정하기 위해 휴리스틱 전략을 채택합니다.
휴리스틱 전략의 구체적인 내용에 대해서는 아직 관련 정보나 문헌을 찾지 못했습니다. 나중에 찾거나 같은 반 친구가 제공하면 추가하겠습니다.
12.4.3 초기-Z
Early-Z는 불필요한 렌더링 패스 객체(화면 공간에 표시되지 않는 픽셀)를 제거하기 위해 빠른 폐색 방법을 제공하는 초기 깊이 테스트입니다. Adreno GPU는 그리기 픽셀 채우기 속도의 4배로 가려진 픽셀을 제거할 수 있습니다.
Early-Z는 일반적으로 래스터라이제이션 후 및 렌더링 패스 단계의 픽셀 음영 처리 전에 발생합니다. (아래 사진)

Early-Z 기술은 많은 유효하지 않은 픽셀을 사전에 제거하여 과도하게 소비되는 픽셀 셰이더에 들어가는 것을 방지할 수 있습니다. Early-Z 컬링의 최소 단위는 1픽셀이 아닌 픽셀 쿼드입니다. 아래는 실행 사례 중 하나입니다.

Early-Z 작동 다이어그램. 왼쪽에는 깊이 버퍼에 저장된 렌더링된 값이 있으며 모두 1입니다. 중간에는 렌더링 준비가 완료된 깊이 값이 2인 모든 영역이 있습니다. 오른쪽에는 Early-Z 기술을 사용하여 제거된 깊이 버퍼보다 큰 픽셀이 있습니다.
Early-Z 기술을 극대화하기 위해 렌더링 엔진(예: UE)은 렌더링 초기 단계에서 특수 패스(예: UE의 PrePass)를 사용하여 모든 불투명 개체의 깊이를 렌더링하고 TBR 아키텍처의 Early-Z 기술을 활용합니다. TBDR 아키텍처를 지원하는 GPU의 경우 이 단계가 필요하지 않습니다.
그러나 다음 상황에서는 Early-Z가 실패할 수 있습니다.
알파 테스트 켜기: 알파 테스트는 픽셀 셰이더 이후 알파 테스트 단계에서 비교해야 하기 때문에 픽셀 셰이더 이전에는 픽셀 제거 여부를 결정할 수 없습니다.
Tex Kill 켜기: 셰이더 코드에 픽셀 폐기 지침이 있습니다(DX의 폐기, OpenGL의 클립).
깊이 테스트 끄기: Early-Z는 깊이 테스트가 켜진 상태를 기반으로 합니다. 심도 테스트가 꺼진 경우 Early-Z 기술을 활성화할 수 없습니다.
Alpha To Coverage 켜기: Alpha To Coverage는 다중 샘플링을 켜서 주변 픽셀에 영향을 미칩니다. 그러나 Early-Z 단계에서는 주변 픽셀이 잘려졌는지 여부를 알 수 없으므로 미리 제거할 수 없습니다.
후속 색상을 혼합해야 하는 기타 작업.
12.4.4 거래 제거
**트랜잭션 제거(TE)**는 Mali GPU 아키텍처의 주요 대역폭 절약 기능으로 SoC(시스템 온 칩)의 에너지를 크게 절약할 수 있습니다.
TE를 실행할 때 GPU는 현재 프레임 버퍼를 이전에 렌더링된 프레임과 비교하고 수정된 특정 부분만 부분적으로 업데이트하므로 프레임당 외부 메모리로 전송되는 데이터의 양이 크게 줄어듭니다. 비교는 타일 세분성에서 수행되며 CRC(Cyclic Redundancy Check) 서명을 사용하여 타일이 수정되었는지 여부를 확인합니다(동일한 CRC 서명이 있는 타일은 동일한 것으로 간주되므로 타일의 데이터 전송이 무시됩니다).
CRC(Cyclic Redundancy Check)는 네트워크 데이터 패킷, 컴퓨터 파일, 메모리 데이터 스트림 및 기타 데이터를 기반으로 짧은 고정 숫자 검사 코드를 생성하는 해시 함수입니다. 주로 데이터 전송이나 저장 후에 발생할 수 있는 오류를 감지하거나 검증하는 데 사용됩니다. 이는 Mali GPU에서 이 프레임의 타일 데이터가 이전 프레임 버퍼 데이터와 동일한지 여부를 감지하는 데 사용됩니다.

TE 기술 운영 요약. 현재 프레임은 각 블록에 대한 CRC 키 값을 계산하여 다음 프레임에서 각 블록에 데이터 변경이 있는지 비교하고 변경되지 않은 블록에 대해서는 데이터 전송을 취소합니다. 사진 오른쪽 하단의 녹색 블록은 이전 프레임과 일치하므로 프레임 버퍼로 데이터를 전송할 필요가 없습니다. 대화형 게임의 경우 대역폭은 평균 20% 이상 줄어들 수 있습니다.
TE 기술 수행은 최종 이미지 품질에 영향을 미치지 않으며 프레임 버퍼 정확도 요구 사항에 관계없이 GPU가 지원하는 모든 프레임 버퍼 형식을 사용하는 모든 응용 프로그램에서 사용할 수 있습니다. 또한, Tile이 시스템 메모리(Frame Buffer)에 데이터를 쓸 때 TE가 발생한다는 점에 유의해야 한다(아래 그림의 왼쪽 하단).

12.4.5 순방향 픽셀 킬
**FPK(Forward Pixel Kill)**는 OverDraw를 줄이기 위해 Mali-T62X 및 T678 이상 칩에 내장된 기술입니다.
FPK를 지원하는 GPU에서는 픽셀 셰이딩 스레드가 시작되더라도 되돌릴 수 없게 완료되지 않습니다. 렌더링 파이프라인이 이후 스레드가 동일한 픽셀 위치에 불투명 데이터를 쓸 것임을 발견하면 진행 중인 계산이 언제든지 종료될 수 있습니다. 각 스레드를 완료하는 데 제한된 시간이 걸리기 때문에 이미 파이프라인에 있는 픽셀을 죽이는 데 활용할 수 있는 시간이 있습니다. 실제로 파이프라인의 깊이는 미래에 대한 예측 효과를 시뮬레이션하는 데 사용됩니다.
FPK를 지원하는 GPU 칩에는 FIFO(선입 선출) 버퍼가 있습니다(Early Z 테스트와 픽셀 셰이더 사이, 아래 그림 참조). 이는 Eearly-Z 테스트를 통과하고 픽셀 셰이딩 계산에 들어가려는 Quad를 저장하는 데 사용됩니다.

FPK의 작동 메커니즘을 설명하기 위해 구체적인 예를 들어보세요. 다음 그림을 예로 들어 보겠습니다.

위 그림의 새로운 쿼드(위치 10, 깊이 0)는 EarlyZ 테스트를 통과했으며 FPK FIFO 버퍼에 들어가려고 합니다. FIFO에 위치 10이 이미 존재하고 깊이가 10인 것으로 확인되었습니다. 새 쿼드는 FIFO 대기열의 쿼드를 대체합니다(새 깊이가 화면에 더 가깝기 때문). 즉, FPK FIFO의 쿼드는 동일한 위치와 더 작은(더 가까운) 깊이의 새로운 쿼드로 대체됩니다.
FPK에 대해 몇 가지 추가 참고 사항을 추가해야 합니다.
FPK 컬링 세분성은 쿼드(2x2 픽셀 블록)입니다.
FPK는 불투명한 물체에만 작동합니다.
FPK가 작동하려면 깊이 테스트를 활성화해야 합니다.
12.4.6 숨겨진 표면 제거
**HSR(Hidden Surface Removal)**은 Hidden Surface Removal으로 번역되며 PowerVR 칩 전용 기술입니다. HSR 기술을 통해 드로잉 순서에 관계없이 OverDraw Zero를 달성할 수 있습니다.

왼쪽 하단은 가려진 픽셀에 대해 컬링을 수행하지 않는 기존 GPU이고, 오른쪽 하단은 PowerVR이 HSR을 사용하여 픽셀 수준 컬링을 달성할 수 있음을 보여줍니다.
Early-Z 테스트를 포함하는 아키텍처에서 애플리케이션은 앞에서 뒤로 그리기 호출을 제출하여 일부 OverDraw를 피할 수 있습니다. 이 순서로 제출하면 깊이 버퍼가 구축되므로 카메라에서 멀리 있는 가려진 픽셀을 조기에 선별할 수 있습니다. 그러나 이는 장면의 카메라나 개체가 움직일 때마다 그림의 순서를 지정해야 하기 때문에 응용 프로그램에 추가적인 부담을 줍니다. 또한 Draw-by-draw 정렬이 매우 조잡하기 때문에 모든 OverDraw를 제거할 수는 없습니다. 예를 들어, 객체 교차로 인한 OverDraw를 해결할 수 없습니다. 또한 그래픽 API 상태 변경을 최소한으로 유지하기 위해 애플리케이션이 그리기 호출 순서를 지정하는 것을 방지합니다.
PowerVR의 TBDR을 사용하면 HSR은 객체가 제출되는 순서(정렬되지 않음)에 관계없이 OverDraw를 완전히 방지합니다. HSR은 순차적 드로잉에 의존하지 않는 픽셀 수준의 제거를 달성할 수 있습니다. 주요 방법은 프리미티브가 래스터라이제이션된 후 먼저 픽셀이 속한 프리미티브(삼각형)를 표시하고 이를 태그 버퍼에 저장하는 것입니다. 장면의 모든 프리미티브가 처리된 후 프래그먼트 셰이더로 들어갑니다. HSR 단계는 래스터라이제이션 후, 픽셀 음영 처리 전입니다.

12.4.7 저해상도 Z 패스
LRZ라고도 하는 저해상도 Z 패스는 TBR이 Early-Z 제거를 수행할 때 Adreno A5X 이상 칩을 위한 최적화 기술입니다.
Binning Pass 단계에서 GPU는 Binning 단계의 성능을 향상시키기 위해 LRZ-Tile(Bin Tile이 아님) 세분성으로 폐색된 영역을 제거하기 위해 저해상도 Z 버퍼를 구성합니다. 이 LRZ는 렌더링 패스에서 전체 해상도 Z 버퍼를 테스트하기 전에 픽셀을 효과적으로 컬링하는 데에도 사용할 수 있습니다.
이 기능의 장점은 메모리 액세스 및 대역폭 감소, 렌더링 기본 요소 감소, 응용 프로그램이 앞에서 뒤로 그릴 필요가 없고 프레임 속도가 향상된다는 점입니다.
그러나 다음 상황에서는 LRZ 기술이 효과적이지 않게 됩니다.
-픽셀 셰이더에 깊이 값을 씁니다.
그래픽 API(Vulkan)의 보조 명령 버퍼를 사용합니다.
IMR을 직접 렌더링해야 하는 모든 조건.
12.4.8 FlexRender
FlexRender는 Adreno 칩의 고유한 기술입니다. TBR(Binning)과 IMR(Direct Rendering) 두 가지 모드를 혼합한 렌더링 기술입니다. 두 모드를 동적으로 전환하여 성능을 극대화합니다.

FlexRender 작동 다이어그램. 직접 렌더링 모드에서 GPU는 GMEM을 우회하고 시스템 메모리와 직접 상호 작용합니다. 비닝 모드에서 GPU는 GMEM을 통해 시스템 메모리와 상호 작용합니다.
드라이버와 GPU는 지정된 렌더 대상의 렌더링 매개변수를 분석하고 자동으로 모드를 선택합니다. 예를 들어, 렌더 타겟의 크기가 매우 작은 경우 렌더링 소비를 줄이기 위해 IMR 모드로 적극적으로 전환합니다(TBR에는 기본 소비가 있습니다). 오클루전 컬링이 수행되면 IMR 모드로 전환됩니다(이전에 TBR 모드였더라도).
일반적으로 IMR 모드는 TBR 모드보다 더 많은 에너지를 소비합니다.

GFXBench Manhattan 3.0으로 모니터링한 Direct 및 Binning 모드에서 Snapdragon SoC의 에너지 소비를 비교하면 후자는 약 20%를 절약합니다.
12.4.9 범용 대역폭 압축
**UBWC(범용 대역폭 압축)**는 Adreno A5x 이상 칩에 추가된 범용 대역폭 압축 기술입니다. 이는 시스템 메모리의 유효 처리량을 향상시키고 데이터 대역폭을 최소화하여 상당한 에너지 절감을 달성할 수 있는 고유한 예측 대역 압축 방식입니다.
GPU 칩 외에도 스냅드래곤 CPU의 디스플레이, 비디오, 카메라 등 여러 구성요소에 UBWC 기술이 적용됐다. 압축은 YUV, RGB 포맷을 지원해 메모리 병목 현상을 줄여준다.
UBWC는 Qualcomm의 칩에 적용되었지만 Google Developers는 Universal Bandwidth Compression To Freedreno Driver를 통해 해당 기술이 실제로 Freedreno 오픈소스 드라이버에서 제공되는 것을 보여줍니다. UBWC에서 사용하는 특정 압축 알고리즘은 이 문서에서 언급되지 않습니다.
12.4.10 암 프레임 버퍼 압축
**AFBC(Arm Frame Buffer Compression)**는 Arm이 설계한 GPU용으로 특별히 설계되었으며 모바일 장치의 열 제약 내에서 점점 더 복잡해지는 디자인을 만드는 어려움을 해결합니다. 가장 중요한 응용 프로그램은 비디오 후처리입니다. 많은 사용 사례에서 GPU는 비디오 스트림을 2D 또는 3D 장면의 텍스처로 사용할 때 비디오를 읽고 특수 효과를 적용해야 합니다. 이 경우 AFBC는 공간적으로 조정된 이미지 데이터를 전송하는 데 드는 전체 시스템 수준 대역폭과 전력 비용을 최대 50%까지 줄일 수 있습니다.

AFBC 작동 다이어그램.
무손실 압축 프로토콜 및 형식인 AFBC는 SoC의 IP 블록 간에 전송되는 데이터 양을 최소화합니다. 구체적으로 AFBC는 다음과 같은 특징을 가지고 있습니다.
무손실 압축 형식. 압축 형식은 원본 이미지 정확도를 유지하며 압축률은 다른 무손실 압축 표준과 비슷합니다.
Mali GPU에서 완벽하게 지원됩니다.
에너지 소비를 줄입니다. 주로 대역폭 감소의 이점을 누릴 수 있습니다.
SoC는 높은 면적 효율로 설계되었습니다. AFBC는 면적 비용 없이 설계에 추가할 수 있습니다.
제한된 최악의 경우 압축 비율. 최악의 경우(랜덤 액세스) 효율성은 4x4 수준으로 떨어집니다.
YUV 및 RGB 형식을 지원합니다. YUV 압축률은 일반적으로 50%입니다.
12.4.11 인덱스 기반 버텍스 셰이딩
**IDVS(Index-Driven Vertex Shading)**는 각 렌더 패스의 버텍스 처리 단계에서 발생하는 Mali GPU 내의 버텍스 처리 최적화 기술입니다.
IDVS의 주요 기능은 기존 버텍스 셰이더를 두 단계로 분할하는 것입니다.
첫 번째 단계는 다양한 정점을 Culling하기 전에 발생하는 Position Shading입니다. 이 단계에서는 꼭지점 위치만 변환하고 꼭지점에 대한 다른 작업은 수행하지 않습니다.
두 번째 단계는 다양한 형태의 Vertex Culling 이후에 발생하는 Varying Shading입니다. 다양한 형태의 Culling을 통과한 정점들만을 처리하며, 정점들의 위치 변환 이외의 작업을 수행합니다.

IDVS는 버텍스 셰이더를 위치 셰이딩과 가변 셰이딩의 두 단계로 나눕니다.
IDVS 기술의 장점은 다음과 같습니다.
대부분의 경우 Varying Shading은 Position Shading보다 더 많은 성능을 소비합니다. 많은 비용이 소요되는 Varying Shading 진입을 방지하기 위해 다양한 Vertex Culling 단계를 통해 유효하지 않은 정점을 제거합니다.
IDVS 기술의 버텍스 어트리뷰트 레이아웃을 일치시킴으로써 데이터 읽기 양을 줄이고, 캐시 적중률을 향상시키며, 성능을 향상시키고, 전력 소모를 줄일 수 있습니다. IDVS 기술과 일치하는 버텍스 어트리뷰트 레이아웃은 다음과 같습니다.
정점의 위치는 데이터 스트림으로 분리됩니다. 데이터 흐름 레이아웃은 다음과 같습니다.
xyz | xyz | xyz | ...- 예를 들어 SoA(Structure of Array)에 따라 위치를 제외하고 정점의 속성을 배치합니다.
color,uv,normal | color,uv,normal | color,uv,normal | ...
IDVS 버텍스 데이터 스트림 분할 최적화 및 상호 작용 다이어그램.
12.4.12 픽셀 로컬 저장소
**PLS(Pixel Local Storage)**는 OpenGL ES의 데이터 액세스 방법입니다. PLS로 선언된 데이터는 GPU의 타일 버퍼에 저장됩니다(아래 그림).

PLS가 활성화되면 렌더링 파이프라인은 색상 작업, 혼합 등을 효율적으로 수행할 수 있습니다. GLSL은 다음 표에 설명된 세 가지 유형의 PLS 데이터 키워드가 있음을 선언합니다.
키워드 기능
__pixel_localEXT 데이터를 읽고 쓸 수 있습니다.
__pixel_local_inEXT 읽기 전용 데이터입니다.
__pixel_local_outEXT 데이터만 씁니다.
PLS의 적용은 디퍼드 렌더링(Deferred Shading)을 예로 듭니다. 의사 코드는 다음과 같습니다.
// ------GBuffer------
__pixel_local_outEXT FragData // 오직 데이터
{
layout(rgba8) highp vec4 Color;
layout(rg16f) highp vec2 NormalXY;
layout(rg16f) highp vec2 NormalZ_LightingB;
layout(rg16f) highp vec2 LightingRG;
}gbuf;
void main()
{
gbuf.Color = CalcDiffuseColor();
vec3 Normal = CalcNormal();
gbuf.NormalXY = Normal.xy;
gbuf.NormalZ_LightingB.x = Normal.Z;
}
// ------라이팅 누적(Accumulate)------
__pixel_localEXT FragData // 데이터
{
layout(rgba8) highp vec4 Color;
layout(rg16f) highp vec2 NormalXY;
layout(rg16f) highp vec2 NormalZ_LightingB;
layout(rg16f) highp vec2 LightingRG;
}gbuf;
void main()
{
vec3 Lighting = CalcLighting(gbuf.NormalXY, gbuf.NormalZ_LightingB.x);
gbuf.LightingRG += Lighting.xy;
gbuf.NormalZ_LightingB.y += Lighting.z;
}
// ------셰이딩 ------
__pixel_local_inEXT FragData // 오직 데이터
{
layout(rgba8) highp vec4 Color;
layout(rg16f) highp vec2 NormalXY;
layout(rg16f) highp vec2 NormalZ_LightingB;
layout(rg16f) highp vec2 LightingRG;
}gbuf;
out highp vec4 FragColor;
void main()
{
FragColor = resolve(gbuf.Color, gbuf.LightingRG, gbuf.NormalZ_LightingB.y);
}PLS를 사용하여 디퍼드 렌더링을 수행하는 작업 다이어그램은 다음과 같습니다(오른쪽 상단에 있는 작은 사각형의 빨간색은 렌더링 기하학 데이터 단계를 나타내고 녹색은 렌더링 조명 단계를 나타냄).

OpenGL ES 외에도 Metal, Vulkan 및 D3D와 같은 그래픽 API는 GPU 타일에서 데이터 작업을 지원하는 해당 인터페이스, 키워드 또는 태그도 제공합니다.
위의 코드는 deferred shading에 필요한 GBuffer 데이터가 항상 PLS에 있었음을 보여줍니다. GBuffer를 시스템 메모리에 다시 쓰지 않고 최종 색상을 구문 분석하고 반환하는 것이 가장 좋습니다(아래 그림).

PLS는 성능을 약 22% 향상시킬 수 있습니다.

UE4는 또한 효율적인 파티클 소프트 믹싱을 위해 PLS를 사용합니다:

왼쪽: 입자 일반 혼합 모드; 오른쪽: 입자 소프트 블렌딩 모드.
Vulkan에도 Subpass라는 유사한 메커니즘이 있습니다. 이후 장을 참조하세요.
12.4.13 서브패스
subpass는 TB(D)R 하드웨어 아키텍처를 준수하는 제품으로 Vulkan, DX12, Metal 등 최신 그래픽 API에 적합합니다. 기본 원칙은 Pixel Local Storage와 유사합니다.
Subpass를 사용하려면 다음과 같은 특별한 요구 사항을 충족해야 합니다.
모든 서브패스는 동일한 렌더 패스에 있어야 합니다.
주변 이웃 픽셀을 샘플링할 필요가 없습니다. (그렇지 않으면 타일 전체에서 데이터에 액세스하게 되며 모든 데이터 액세스는 동일한 타일 내에서 유지될 수 없습니다.)
GPU는 TB(D)R 하드웨어 아키텍처를 지원합니다.
Vulkan, DX12, Metal 등과 같은 최신 그래픽 API
각 RenderPass 및 Subpass는 각 첨부 파일에 대해 loadOp 및 storeOp를 지정하여 액세스 동작을 정확하게 제어할 수 있습니다.


하위 패스에는 세 가지 유형의 loadOp 태그가 있습니다.
LOAD_OP_LOAD: 전역 메모리에서 타일로 첨부 파일을 로드합니다.
LOAD_OP_CLEAR: 타일 버퍼의 데이터를 정리합니다.
LOAD_OP_DONT_CARE: 타일 버퍼의 데이터에 대해 어떤 작업도 수행하지 않습니다. 일반적으로 타일의 모든 데이터가 재설정되며 효율성은 LOAD_OP_CLEAR보다 높습니다.
위 세 가지 태그 실행의 효율성: LOAD_OP_DONT_CARE > LOAD_OP_CLEAR > LOAD_OP_LOAD. Vulkan 사용 샘플 코드:
VkAttachmentDescription colorAttachment = {};
colorAttachment.format = VK_FORMAT_B8G8R8A8_SRGB;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
// loadOp로 DONT_CARE.
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;하위 패스에는 두 가지 유형의 storeOp 태그가 있습니다.
STORE_OP_STORE: Tile의 데이터를 전역 메모리에 저장합니다.
STORE_OP_DONT_CARE: 타일 버퍼의 데이터에 대해 저장 작업이 수행되지 않습니다.
위 두 태그의 실행 효율성: STORE_OP_DONT_CARE > STORE_OP_STORE. Vulkan 사용 샘플 코드:
VkAttachmentDescription colorAttachment = {};
colorAttachment.format = VK_FORMAT_B8G8R8A8_SRGB;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
// loadOp로 DONT_CARE.
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
// storeOp로 DONT_CARE.
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;타일에서 변수를 선언하기 위해 셰이더에 명시적 키워드(__pixel_localEXT, __pixel_local_inEXT, __pixel_local_outEXT)가 있는 OpenGL ES와 달리 Vulkan은 첨부 파일을 타일에 저장하려면 TRANSIENT_ATTACHMENT 및 LAZILY_ALLOCATED 태그를 사용해야 합니다.
VkImageCreateInfo imageInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
imageInfo.flags = flags;
imageInfo.imageType = type;
imageInfo.format = format;
imageInfo.extent = extent;
imageInfo.samples = sampleCount;
// Image을(를) 활용하여 TRANSIENT_ATTACHMENT의 플래그 .
imageInfo.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
VmaAllocation memory;
VmaAllocationCreateInfo memoryInfo{};
memoryInfo.usage = memoryUsage;
// Image의 메모리 을(를) 활용하여 LAZILY_ALLOCATED의 플래그 .
memoryInfo.preferredFlags = VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
// 생성(Create)Image.
auto result = vmaCreateImage(device.get_memory_allocator(), &imageInfo, memoryInfo, &handle, &memory, nullptr);Subpass의 loadOp 및 storeOp를 사용하여 최적화한 후 Vulkan의 공식 테스트 예는 전역 메모리 읽기를 36%, 전역 메모리 쓰기를 62%, 조각 실행 주기를 7% 줄일 수 있음을 보여줍니다.

또한 올바른 storeOp 및 loadOp를 사용하면 Tile에서 MSAA 데이터를 효율적으로 구문 분석할 수 있습니다. 구체적인 지침은 다음과 같습니다.
- MSAA가 포함된 이미지(또는 첨부 파일)는 일시적이어야 합니다. MSAA 구문 분석 후의 데이터는 다음 태그를 통해 렌더 패스 종료 시 얻을 수 있습니다.
로드옵 = LOAD_OP_CLEAR;
매장운영 = STORE_OP_DONT_CARE;
LAZILY_ALLOCATED 메모리 태그를 사용합니다.
하위 패스에서 pResolveAttachments 태그를 사용합니다.
깊은 템플릿을 부착하는 경우에도 유사한 효과를 얻을 수 있습니다.
VK_KHR_length_stencil_resolve 플래그를 사용하세요.
- Vulkan 1.2 이상의 API에서만 지원됩니다.
위의 방법을 통해 MSAA 데이터를 전역 메모리로 전송하지 않고도 Tile에서 MSAA 데이터를 효율적으로 구문 분석할 수 있습니다. 또한 MSAA를 해결하려면 vkCmdResolveImage 인터페이스를 사용하지 않아야 합니다.


상단: vkCmdResolveImage를 사용하여 MSAA를 구문 분석하는 잘못된 데모입니다. 하단: Tile을 사용하여 MSAA를 구문 분석하는 올바른 데모입니다.
MSAA 구문 분석을 최적화하기 위해 subpass의 loadOp 및 storeOp를 사용한 후 Vulkan의 공식 테스트 예에서는 전역 메모리 읽기를 261%, 전역 메모리 쓰기를 440% 줄일 수 있음을 보여줍니다! !

최적화 효과는 분명합니다! ! 당신은 무엇을 기다리고 있습니까? 애플리케이션을 최적화하려면 서브패스의 유리한 무기를 선택하세요! !
자세한 지침은 Vulkan의 공식 조직인 KhronosGroup의 github: 렌더 패스 첨부 파일의 적절한 사용을 참조하세요.
UE의 서브패스 캡슐화에 대한 자세한 내용은 10.4.4.2 서브패스 렌더링을 참조하세요.
12.4.14 적응형 확장 가능한 텍스처 압축
**ASTC(Adaptive Scalable Texture Compression)**는 Arm과 AMD가 공동 개발한 텍스처 압축 형식입니다. ETC 및 ETC2의 고정 블록 크기(4x4)와 달리 ASTC는 가변 블록 크기 압축을 지원하므로 더 높은 압축률로 유연한 텍스처 데이터를 얻고 GPU 대역폭과 에너지 소비를 줄입니다.
ASTC는 아직 OpenGL의 표준 형식이 되지 않았고 확장 형태로만 존재하지만 현재 주류 GPU에서 널리 지원되며 표준 표준 확장은 아닙니다. 그러나 Vulkan에서는 ASTC가 이미 표준 기능입니다. 특히 ASTC는 다음 기능을 지원합니다.
- **유연한 형식.**ASTC는 RGB+A(상관 RGB, 비상관 알파)와 같은 비상관 채널을 포함하여 1~4개 채널 사이에서 데이터를 압축할 수 있습니다. 그리고 블록 크기는 4x4, 5x4, 6x5, 10X5 등과 같이 가변적입니다.
Adreno A5X 이상의 GPU 칩은 다양한 블록 크기(2차원 및 3차원 포함)의 다음 ASTC 형식을 지원합니다.
ASTC_4X4
ASTC_5X4
ASTC_5X5
ASTC_6X5
ASTC_6X6
ASTC_8X5
ASTC_8X6
ASTC_8X8
ASTC_10X5
ASTC_10X6
ASTC_10X8
ASTC_10X10
ASTC_12X10
ASTC_12X12
ASTC_3X3X3
ASTC_4X3X3
ASTC_4X4X3
ASTC_4X4X4
ASTC_5X4X4
ASTC_5X5X4
ASTC_5X5X5
ASTC_6X5X5
ASTC_6X6X5
ASTC_6X6X6
**유연한 비트 전송률.**ASTC는 이미지를 압축할 때 텍셀당 0.89비트에서 8비트(bpt) 사이의 다양한 비트 전송률을 제공합니다. 비트 전송률 선택은 색상 형식 선택과 관계가 없습니다. 그러나 기존 ETC 및 기타 형식은 정수 비트 전송률만 가질 수 있습니다.
**고급 형식 지원.**ASTC는 LDR(낮은 동적 범위), LDR sRGB, HDR(높은 동적 범위) 색상 공간의 이미지를 압축할 수 있으며 3D 볼륨 텍스처도 압축할 수 있습니다.
**이미지 품질을 향상시킵니다.**높은 수준의 형식 유연성에도 불구하고 ASTC는 동일한 비트 전송률에서 거의 모든 기존 텍스처 압축 형식(ETC2, PVRCT, BC 등)보다 이미지 품질이 더 뛰어납니다.
**포맷 매트릭스의 전체 범위.**ASTC가 등장하기 전에는 다음 그림과 같이 기존 텍스처 압축 형식이 상대적으로 적은 수의 색상 형식과 비트 전송률 조합을 지원했습니다.

위 형식은 그래픽 API나 운영 체제에 의해서도 제한되므로 단일 플랫폼에 대한 압축 옵션은 매우 제한됩니다. ASTC의 출현은 위의 문제를 해결하고 필요한 형식 매트릭스를 거의 완벽하게 커버하여 콘텐츠 제작자에게 다양한 비트 전송률 선택을 제공합니다. 아래 이미지는 사용 가능한 형식과 비트 전송률을 보여줍니다.

ASCT는 위의 목표를 어떻게 달성합니까? 그 대답은 ASTC가 특별한 압축 알고리즘과 데이터 구조를 사용한다는 사실에 있습니다. ASTC의 알고리즘 기술의 핵심 내용과 설명은 다음과 같습니다.
- 블록 압축
실시간 그래픽의 압축 형식은 무작위 샘플을 텍스처로 빠르고 효율적으로 변환할 수 있어야 하므로 압축 기술은 다음을 수행해야 합니다.
샘플링 좌표만 주어지면 메모리에 있는 데이터의 주소를 계산합니다.
- 주변 데이터를 너무 많이 압축 해제하지 않고 임의 샘플의 압축을 해제하는 기능.
ASTC를 포함한 모든 최신 실시간 압축 형식에서 사용되는 표준 솔루션은 이미지를 고정 크기의 픽셀 블록으로 분할한 다음 각 블록을 고정된 수의 출력 비트로 압축하는 것입니다. 이는 셰이더가 좋은 압축 해제 비용으로 어떤 순서로든 빠르게 텍셀에 액세스할 수 있음을 보장합니다.
ASTC의 2D 블록 공간 범위는 4x4 텍셀부터 12x12 텍셀까지이며 모두 128비트 출력 블록으로 압축됩니다. 형식 비트 전송률은 128비트를 점유된 공간의 픽셀 수로 나누어 구하며, 그 범위는 8bpt(

- 색상 끝점
블록의 색상 데이터는 두 색상 끝점 사이의 그라데이션으로 인코딩됩니다. 각 텍셀은 그래디언트를 따라 위치를 선택한 다음 압축 해제 중에 보간됩니다. ASTC는 엔드포인트 모드라고 하는 16색 엔드포인트 인코딩 방식을 지원합니다. 엔드포인트 모드 옵션을 사용하면 다음을 변경할 수 있습니다.
색상 채널의 수입니다. 예: 밝기, 밝기+알파, rgb 또는 rgba.
인코딩 방법. 예: 직접, 베이스+오프셋, 베이스+스케일 또는 양자화 수준.
데이터 범위. 예: 낮은 동적 범위 또는 높은 동적 범위.
블록별로 다양한 엔드포인트 모드와 엔드포인트 색상 BISE 양자화 수준을 선택할 수 있습니다.
- 색상 파티션
블록 내의 색상은 복잡한 경우가 많으며 단색 그라디언트는 블록 내의 모든 색상을 정확하게 캡처하지 못하는 경우가 많습니다. 예를 들어, 다음 그림과 같이 푸른 잔디 위에 놓여 있는 빨간 공을 두 가지 색상으로 나누어야 합니다.

ASTC를 사용하면 단일 블록이 파티션이라고 하는 최대 4개의 색상 그라데이션을 참조할 수 있습니다. 압축 해제를 위해 각 텍셀은 별도의 파티션에 할당됩니다.
각 텍셀에 대한 파티션 할당을 직접 저장하려면 모든 블록 크기를 저장하기 위한 광범위한 압축 해제 하드웨어가 필요합니다. 대신 ASTC는 분할된 인덱스를 시드 값으로 사용하여 알고리즘 방식으로 패턴 시퀀스를 생성합니다. 압축 프로세스는 각 블록에 대해 가장 잘 일치하는 패턴을 선택하고, 블록은 가장 잘 일치하는 패턴의 인덱스만 저장하면 됩니다. 다음 그림은 2(이미지 상단), 3(이미지 중간), 4(이미지 하단) 파티션의 8 × 8 블록 크기에 의해 생성된 패턴을 보여줍니다.

파티션 수와 파티션 인덱스는 블록별로 선택할 수 있으며, 각 파티션마다 다른 색상 끝점 패턴을 선택할 수 있습니다.
- 색상 코딩
ASTC는 그라데이션을 사용하여 각 텍셀의 색상 값을 지정합니다. 각 압축 블록은 그라디언트의 끝점 색상과 각 픽셀의 보간 가중치를 저장합니다. 압축을 푸는 동안 각 픽셀의 색상 값은 각 픽셀의 가중치를 기준으로 두 끝점 색상 사이를 보간하여 생성됩니다. 아래 이미지는 다양한 텍셀 가중치의 보간을 보여줍니다.

사각형에는 녹색 잔디 위에 놓인 빨간 공과 같이 복잡한 색상 분포가 포함되는 경우가 많습니다. 이러한 경우 단일 색상 그라데이션으로는 다양한 텍셀 색상 값을 모두 정확하게 표현할 수 없습니다. ASTC를 사용하면 블록이 파티션이라고 하는 최대 4개의 서로 다른 색상 그라데이션을 정의하고 각 텍셀을 별도의 파티션에 할당할 수 있습니다. 아래 이미지는 파티션 인덱스가 각 텍셀에 대한 색상 그라데이션을 지정하는 방법을 보여줍니다(두 개의 파티션, 하나는 빨간 공 픽셀용이고 다른 하나는 녹색 잔디 픽셀용).

- 알파벳 저장
각 픽셀의 색상 및 가중치 값은 이론적으로 부동 소수점 값이지만 실제 값을 직접 저장하기에는 비트가 너무 적습니다. 저장 크기를 줄이려면 압축 중에 이러한 값을 양자화해야 합니다. 예를 들어, 0.0~1.0 범위의 각 텍셀에 대한 부동 소수점 가중치가 있는 경우 0.0, 0.25, 0.5, 0.75, 1.0의 5개 값으로 양자화하도록 선택한 다음 정수 0~4를 사용하여 저장소에 이러한 5개의 양자화된 값을 나타낼 수 있습니다.
일반적으로 N개의 레이어를 양자화하려면 N개의 기호가 포함된 문자 테이블에 문자를 효율적으로 저장할 수 있어야 합니다. N 기호 테이블에는 각 문자에 대한 정보의 log2(N) 비트가 포함되어 있습니다. 5개의 가능한 기호로 구성된 문자 테이블이 있는 경우 각 문자에는 약 2.32비트의 정보가 포함되지만 간단한 이진 저장에는 3비트로 반올림이 필요하며 이는 저장 용량의 22.3%를 낭비합니다. 아래 차트는 간단한 이진 인코딩을 사용하여 임의의 N 기호 문자 테이블을 저장함으로써 낭비되는 비트 공간의 비율을 보여줍니다.

위 차트는 대부분의 문자 크기에 대해 문자당 정수 비트 수를 사용하면 저장 용량이 많이 낭비된다는 것을 보여줍니다. 압축 형식의 경우 효율성이 중요하므로 ASTC가 해결해야 할 문제입니다.
한 가지 해결책은 추가 비트가 낭비되지 않도록 양자화 수준을 다음 2의 거듭제곱으로 반올림하는 것입니다. 그러나 이 솔루션은 인코더가 다른 곳에서 더 큰 이득을 얻는 데 사용될 수 있는 비트를 소비하도록 강제하므로 이 솔루션은 이미지 품질을 저하시키며 최적의 솔루션이 아닙니다.
- Quint and trit
보다 효율적인 솔루션은 5중 문자 1개를 3비트로 결합하는 대신 5중 문자 3개를 결합하는 것입니다. 6.97비트의 정보를 포함하는 5개의 문자에 3개의 문자 조합이
마찬가지로 트라이어드라고 하는 세 기호의 알파벳을 구성하고 세 글자의 문자를 다섯 그룹으로 결합할 수 있습니다. 각 문자 그룹에는 7.92비트 정보를 포함하는
- 제한된 정수 시퀀스 인코딩
ASTC에서 사용하는 BISE(Bounded Integer Sequence Encoding)를 사용하면 최대 256개의 기호까지 임의 문자를 사용하여 문자 시퀀스를 저장할 수 있습니다. 각 문자 크기는 가장 공간 효율적인 비트, 메타 및 5중을 사용하여 인코딩됩니다.
최대
최대
기호를 포함하는 알파벳은 문자당 n 비트(m) 및 트리트(t)를 사용하여 인코딩될 수 있으며 방정식 을 사용하여 재구성될 수 있습니다. 최대
기호를 포함하는 알파벳은 n 비트(m)와 문자당 1퀸트(q)를 사용하여 인코딩될 수 있으며 방정식 을 사용하여 재구성될 수 있습니다.
시퀀스의 문자 수가 3 또는 5의 배수가 아닌 경우 시퀀스 끝에서 저장 공간을 낭비하지 않도록 해야 하므로 인코딩에 또 다른 제약이 추가됩니다. 인코딩할 시퀀스의 마지막 몇 개의 값이 0이면 인코딩된 비트 문자열의 마지막 몇 비트도 0이어야 합니다. 이상적으로는 0이 아닌 비트 수는 계산하기 쉽고 이전에 인코딩된 값의 크기에 의존하지 않습니다. 압축 중에 이를 제대로 처리하기는 어렵지만 가능합니다. 즉, 비트 시퀀스가 0비트라고 안전하게 가정할 수 있으므로 비트 시퀀스가 끝난 후에는 패딩을 저장할 필요가 없습니다.
이 제약 조건과 비트, 삼중수, 오중수의 스마트 패킹을 통해 BISE는 고정된 수의 비트를 사용하여 S 문자열을 N 기호 알파벳으로 인코딩합니다.
S의 최대값은
비트를 사용하여 입니다. S의 최대값은
비트를 사용하여 입니다. S의 최대값은
비트를 사용하여 입니다.
압축기는 저장되는 문자의 크기에 대해 가장 작은 저장 공간을 생성하는 옵션을 선택합니다. 일부는 바이너리를 사용하고, 일부는 비트와 트리트를 사용하고, 일부는 비트와 퀸트를 사용합니다. 다음 그림은 바이너리 스토리지에 비해 BISE 스토리지의 효율성 향상을 보여줍니다.

또한 압축 과정에서 각 블록에 대해 최상의 인코딩이 선택됩니다. 텍셀 가중치 값을 계산할 때 앞서 언급한 BISE 외에도 이중 평면 가중치(Dual-plane Weights) 알고리즘도 있다.
ASTC는 무료로 사용할 수 있고, 통합하기 쉬우며, 많은 주류 시스템과 하드웨어에서 지원됩니다. ASTC를 지원하려면 다음 OpenGL 확장이 필요합니다.
GL_AMD_compressed_ATC_texture
GL_ANDROID_extension_pack_es31a기존 텍스처 압축 형식(ETC, BC, PVRTC 등)과 비교할 때 ASTC를 사용한 압축 효과는 매우 분명하며 이미지 품질은 원본 이미지에 더 가깝고 압축률은 더 높습니다.


왼쪽: 원본 노멀 맵; 중간: ETC로 압축한 효과; 오른쪽: ASTC로 압축한 효과.
이를 통해 얻을 수 있는 직관적인 이점은 메모리와 대역폭을 덜 차지하며 각 프레임에서 대역폭을 약 24.4%만큼 줄일 수 있다는 것입니다.

ASTC에 대한 자세한 내용은 적응형 확장 가능 텍스처 압축을 참조하세요.
12.4.15 빅.리틀 코어
모바일 CPU(Qualcomm Keyo CPU와 같은 GPU가 아님)에는 Arm이 처음 제안한 big.LITTLE 조합 아키텍처가 있습니다. 이 아키텍처에는 빅 코어와 리틀 코어가 모두 있습니다. 빅 코어는 고성능에 최적화되어 있고, 리틀 코어는 에너지 소비에 최적화되어 있습니다.

Qualcomm Keyo CPU의 big.LITTLE 아키텍처. 왼쪽의 4개는 빅 코어로 실행 성능은 높지만 전력 소모가 크다. 오른쪽에 있는 4개는 실행 성능은 낮지만 전력을 절약하는 작은 코어입니다.
big.LITTLE 아키텍처의 특징은 다음과 같습니다.
하나의 SoC에 전혀 다른 두 개의 프로세서를 결합하여 스마트 기기의 성능 요구 변화에 대응합니다.
big.LITTLE 소프트웨어는 적절한 CPU 코어에 대한 작업 할당을 자동으로 처리합니다. 운영 체제는 시스템의 고성능 및 효율적인 코어를 직접 감지하고 성능 요구 사항에 따라 각 작업을 적절한 코어에 동적으로 할당할 수 있습니다.
성능과 전력 효율성을 최적화하려면 이 아키텍처의 기능을 이해하고 사용하는 방법이 중요합니다. 잘 최적화하면 게임 시간이 길어지고 게임이 더 시원해집니다.
big.LITTLE의 효율성을 높이려면 little core를 먼저 사용해 보세요. 예상 프레임 시간이 16ms(60FPS)라고 가정하면 개발자는 Snapdragon Profiler와 같은 도구를 사용하여 작업을 식별하고 이를 LITTLE 코어로 이동할 수 있습니다. 예를 들어 큰 코어에서 실행하는 데 3밀리초가 걸리는 천 시뮬레이션이 있는 게임은 작은 코어에서 실행하는 데 10밀리초가 걸릴 수 있습니다. 실행 시간이 허용되는 한(이 예의 프레임 예산은 16ms), 빅 코어의 사용을 줄이고 전력 효율성을 향상시키기 위해 리틀 코어로 이동해야 합니다.
모바일 SoC 제조업체(예: Qualcomm 및 Arm)는 일반적으로 개발자가 작업을 실행해야 하는 CPU 코어 유형을 지정할 수 있도록 관련 SDK 및 API를 제공합니다. 자세한 내용은 작업 실행 제어를 참조하세요.
12.4.16 기타 기술사항
위 섹션에서 다룬 기술적 사항 외에도 SIMD, SIMT, 통합 셰이더 아키텍처(통합 셰이더 아키텍처, 아래 그림 참조), 스칼라 아키텍처(스칼라 셰이더 아키텍처), Tripipe(아래 그림) 등과 같은 모바일 칩 또는 그래픽 API에는 실제로 많은 다른 기술이 있습니다. 자세한 기술 세부 사항은 GPU에 대한 저자의 다른 기사: 심층적인 GPU 하드웨어 아키텍처 및 작동 메커니즘을 읽을 수 있습니다.

왼쪽: 별도의 셰이더 처리 장치, 오른쪽: 통합 셰이더 처리 장치. 후자의 프로세서는 기본적으로 풀로드에서 실행되므로 대기 및 무부하가 줄어들고 전반적인 컴퓨팅 성능이 향상되는 것을 볼 수 있습니다.

128비트 대역폭, 2x FP64, 4x FP32 및 8x FP16 작업 효율성을 갖춘 3개의 컴퓨팅 유닛, 1개의 액세스 유닛 및 1개의 텍스처 유닛을 포함하는 Mali GPU의 Tripipe 구조의 개략도.
또한 OpenGL ES에는 텍스처 하위 영역에 대한 읽기 및 쓰기 작업과 같이 성능을 향상할 수 있는 많은 확장 기능이 있습니다.
KHR_partial_update
EXT_buffer_age이 확장을 사용하면 호출자가 Backbuffer의 시간을 사용하여 프레임 콘텐츠를 그릴 여러 상자를 지정할 수 있습니다. 이 기술은 TE와 유사하지만 타일 버퍼에 데이터를 쓰지 않습니다.
12.5 모바일 GPU 아키텍처 및 메커니즘
이 장에서는 모바일 GPU의 하드웨어 아키텍처와 작동 메커니즘에 대해 설명합니다.
12.5.1 모바일 GPU 개요
모바일 GPU의 이식성으로 인해 PPA의 세 가지 지표를 고려해야 합니다. 따라서 고성능 GPU를 설계하는 것은 매우 어렵고 매우 어렵습니다. 현재 GPU 제조사는 퀄컴, Arm, 이매지네이션테크 등이 대표적이다. 대표작으로는 Adreno, Mali, PowerVR 등이 있습니다. 모바일 GPU는 일반적으로 SoC에 통합되어 CPU, 메모리 및 기타 장치로 유기적인 하드웨어 아키텍처 시스템을 구성합니다.

스냅드래곤 프레임 다이어그램. CPU, Adreno GPU, 메모리 및 기타 구성 요소를 포함하며 버스, 네트워크 등을 통해 데이터 상호 작용을 수행합니다.
시간이 지남에 따라 모바일 하드웨어가 개발되고 다음과 같이 점점 더 많은 새로운 그래픽 API 및 렌더링 기능이 모바일 터미널로 마이그레이션됩니다.
주류 GPU는 DX12, Vulkan1.2 및 OpenGL ES 3.2와 같은 그래픽 API는 물론 VRS, Mesh Shading, Ray Tracing 및 WaveMath와 같은 새로운 렌더링 기능을 지원합니다.
ALU, 텍스처, 메모리 등을 포함하여 GPU 처리량과 컴퓨팅 성능이 크게 향상되었습니다.

Qualcomm Adreno 640 GPU의 성능 개요(오른쪽에 Xbox One 성능 데이터 포함)
- 메모리 대역폭이 증가하고 에너지 소비율이 향상됩니다.

- 절전 기능이 풍부합니다.
렌더 타겟 압축, FP16 수학 연산, ASTC, Vulkan 서브패스.
UBWC, AFBC, IDVS, PLS 등
모바일 SoC는 VR 애플리케이션에 널리 사용되며 다양한 전용 최적화 기술을 제공합니다.
Compute Shader의 기능이 향상되고 향상되며 OpenCL 라이브러리에 대한 지원도 향상되는 경향이 있습니다.
병렬 수가 증가하고 처리량이 증가합니다.

CPU 및 GPU 작동의 개략도. GPU 캐시는 작지만 스레드 수가 많은 것을 볼 수 있습니다.
모바일 GPU 아키텍처 내의 관련 개념과 명사는 다음과 같이 분석됩니다.
개념 이름 분석하다
암바 고급 마이크로컨트롤러 버스 아키텍처 고급 마이크로컨트롤러 버스 아키텍처
AXI AMBA 고급 확장 가능 인터페이스 AMBA 고급 확장 가능 인터페이스
APB AMBA 고급 주변 버스 AMBA 고급 주변 버스
에이스 AMBA AXI 일관성 확장 AMBA AXI 적합성 확장
GPU 그래픽 처리 장치 그래픽 처리 장치
VPU 비디오 처리 장치 비디오 처리 장치
DPU 디스플레이 처리 장치 디스플레이 처리 장치
이자 명령어 세트 아키텍처 명령어 세트 아키텍처
심드 단일 명령어 다중 데이터 단일 명령 다중 데이터
ISP 이미지 합성 프로세서 합성 이미지 프로세서
TSP 텍스처 및 셰이딩 프로세서 텍스처 및 셰이더 프로세서
12.5.2 모바일 GPU 작동 메커니즘
각 GPU 제조업체, 각 시리즈, 각 세대의 제품의 작동 메커니즘이 다를 수 있으므로, 이 섹션에서는 Mali GPU를 예로 들어 모바일 GPU 작동 메커니즘을 설명합니다. 먼저 Arm Mali T880 GPU 하드웨어 아키텍처의 매개변수를 다음과 같이 설명하겠습니다.
16개의 셰이더 코어(SC).
타일 크기는 16x16(내부 4x4~32x32)입니다.

깊이 템플릿 버퍼, 128비트 픽셀 데이터를 저장할 수 있습니다.
각 픽셀에는 16바이트, 원시 비트 액세스가 있습니다.
GLES3.2, Vulkan 1.0, CL 1.2, DX 11.2를 지원합니다.
4x, 8x, 16x MSAA.

Arm Mali T880 GPU 하드웨어 아키텍처 다이어그램 및 기능 설명.
Mali GPU의 경우 드라이버는 GPU의 드로잉 하드웨어에 작업을 생성하고 제출하는 작업 관리자를 통해 드로잉 작업을 제출합니다. 내부 연결 구성 요소를 통해 상호 작용합니다.

애플리케이션, 드라이버, GPU, DPU 등과 같은 다양한 수준에서의 상호 작용에 대한 단순화된 개략도는 다음과 같습니다.

애플리케이션, 드라이버, GPU 등 간의 상호 작용에 대한 개략도. 그중 eglSwapBuffers는 프레임의 끝을 나타냅니다. 앱은 그리기 명령을 드라이버에 부여하고 드라이버는 작업을 GPU에 할당합니다. GPU 드로잉이 완료된 후 결과가 DPU에 제출됩니다. 다양한 레벨 사이에는 지연이 있습니다.
먼저 애플리케이션 계층과 드라이버 계층 간의 상호 작용을 살펴봅니다. 애플리케이션이 그래픽 API(예: OpenGL ES)를 호출하면 드라이버는 해당 리소스 아키텍처 다이어그램을 생성합니다.

GPU 내부에는 다음과 같은 유형의 작업이 있습니다.
직업 이름 약어 설명
버텍스 작업V 버텍스 세트에서 버텍스 셰이더를 실행합니다.
타일 작업티 타일링 유닛(고정 기능)은 변환된 기본 요소를 오버레이 타일로 분할합니다.
조각 작업젠 모든 타일에서 실행되는 단일 렌더 대상에서 작동합니다.
직업 체인
- 직업 체인.
다음은 GPU 작업 체인의 한 시나리오입니다.

작업 체인 다이어그램. 작업 간에는 종속성이 있습니다(화살표로 표시). 이전 작업이 완료되어야 다음 작업을 실행할 수 있습니다.
CPU와 GPU 간의 상호 작용 다이어그램은 다음과 같습니다. CPU는 APB를 통해 GPU에 작업을 제출하고, GPU의 작업 관리자는 AXI를 통해 공유 메모리에 액세스하며, CPU도 AXI를 통해 공유 메모리에 액세스할 수 있습니다.

GPU의 Job Manager에 대한 정보는 다음과 같습니다.

Job Manager 작동 다이어그램. 그래프에는 버텍스 작업 3개, 타일 작업 1개, 음영 처리 작업 2개가 할당되어 있습니다. 청크 작업은 버텍스 작업에 따라 다릅니다.
Shader Core의 경우 Mali의 구조는 VS 또는 PS를 실행할 수 있는 통합 셰이더 아키텍처인 Tripipe입니다.

또한, Vertex Job 동작의 개략도는 다음과 같다. 버텍스 스레드는 타일 버퍼에 쓰지 않지만 주 메모리에 직접 액세스합니다. 버텍스 작업에는 4n개의 정점이 포함됩니다.

조각 작업의 개략도는 다음과 같습니다.

Fragment Work는 Front-End, Tripipe, Back-End의 3단계로 나누어집니다. 래스터라이제이션, Early-Z 및 FPK를 성공적으로 통과한 픽셀은 Fragment Thread Creator(Quad, 즉 2x2 스레드)에 의해 생성되고 Tripipe 음영 처리에 들어간 다음 Late-Z에 들어가 블렌딩되고 마지막으로 타일 메모리에 기록됩니다.
그러나 모든 모바일 GPU가 Mali와 정확히 동일하게 작동하는 것은 아닙니다. 예를 들어 PowerVR에는 많은 차이점이 있습니다.

PowerVR 시리즈 7XT 아키텍처 다이어그램.

PowerVR 시리즈 7XT 통합 셰이더 클러스터 그룹 아키텍처 다이어그램.
PowerVR에 대한 자세한 소개는 다음을 참조하세요.
개발자를 위한 PowerVR Series5 아키텍처 가이드
PowerVR 그래픽 - 최신 개발 및 향후 계획
12.5.3 병렬성, 끊김 및 지연
무어의 법칙이 둔화되면서 현대 모바일 SoC는 멀티 코어 고병렬화 방향으로 발전하고 있습니다. 애플리케이션이 멀티 코어 성능을 사용하여 병렬 효율성을 향상시킬 수 있는지 여부는 애플리케이션의 품질과 사용자 경험을 크게 좌우합니다.
병렬 효율성과는 반대로 지연과 지연은 실시간 애플리케이션(예: 게임)의 천적입니다. 끊김 현상은 프레임 속도가 낮고 응용 프로그램이 충분히 원활하게 실행되지 않음을 의미합니다. 지연은 작업이 제때에 응답할 수 없음을 의미하며, 이로 인해 제품에 대한 사용자 경험이 저하되고 심각한 사용자 손실로 이어질 수도 있습니다.
PC에서든 모바일에서든 렌더링 파이프라인이 처리해야 하는 장면은 멀티스레딩과 같은 기능과 결합되어 점점 더 복잡해지고 있으므로 대기 및 지연과 같은 현상이 다소 발생하여 지연 시간이 발생합니다. 이러한 현상은 TB(D)R이 널리 퍼져 있는 모바일 렌더링 파이프라인에서 특히 두드러집니다.
지연과 지연에는 객관적이고 주관적인 이유가 있습니다. 객관적인 이유는 멀티 스레드 협력 대기, 동기화, 드라이버 최적화, GPU 내부 실행 메커니즘의 양성 최적화 등을 의미합니다. 주관적인 측면은 특정 렌더링 메커니즘을 준수하는 인터페이스, 태그, 상태 또는 리소스를 사용하지 않는 것을 의미하며 이를 방지하고 최적화할 수 있습니다.

UE에는 게임 스레드, 렌더링 스레드, RHI 스레드가 있습니다. 후자의 스레드는 일반적으로 이전 스레드보다 더 지연됩니다. 이전 스레드가 너무 많은 시간을 끌지 않도록 동기화 및 대기도 있습니다.

애플리케이션, 드라이버, GPU 및 디스플레이 간의 지연 다이어그램. 하위 레이어는 일정 기간 동안 상위 레이어보다 뒤떨어집니다.

OpenGL의 glFinish 및 glFlush 실행 다이어그램. glFlush가 호출된 후 렌더링 지침이 GPU에 즉시 새로 고쳐지지 않을 수 있습니다. 이는 드라이버의 렌더링 명령 버퍼가 가득 찬 경우에만 수행되며 이로 인해 지연이 발생할 수도 있습니다.
모바일 GPU TB(D)R에 대한 일반적인 접근 방식은 Binning Pass와 Rendering Pass를 서로 다른 프레임에서 처리하여 병렬 효율성을 향상시키는 것이지만 이로 인해 지연이 발생할 수도 있습니다.

TBR 아키텍처의 비닝 및 렌더링 프레임 오류 처리에 대한 개략도.
위의 경우는 완벽한 프레임 오류 처리를 한 경우입니다. 다음 상황 중 하나가 발생하면 TBR의 실행 리듬이 중단되고 더 심각한 중단 및 지연이 발생합니다.
- 비닝은 이전 프레임의 데이터나 리소스에 의존합니다.

프레임 n+1의 비닝은 프레임 n의 렌더링 결과에 따라 달라지므로 프레임 n의 렌더링 패스와 병렬로 처리할 수 없으며 다음 프레임으로만 지연될 수 있습니다.
이 상황은 지연된 사용을 통해 해결될 수 있습니다. 예를 들어, N 프레임의 비닝은 N-1 프레임의 렌더링 결과를 사용합니다. 다음 그림은 실시간 환경 스테레오그램의 최적화 사례입니다.

- 데이터는 제출 후 렌더링 및 사용 전에 수정되어야 합니다. 예를 들면:
픽셀 셰이더는 데이터를 계산하고 프레임 버퍼 개체에 기록하며 그 결과를 사용하여 변위를 생성합니다.
- CPU에서 텍스처를 작성하고 이를 사용하여 렌더링한 다음 텍스처를 다시 업데이트하고 다음 프레임을 렌더링합니다. 픽셀 셰이더는 텍스처 업데이트가 완료될 때까지 실행되지 않습니다.
Vulkan과 같은 최신 그래픽 API에는 Subpass 메커니즘이 있습니다. 서브패스는 병렬(오버랩)로 처리되거나 데이터 종속성을 지정할 수 있습니다.


상단: 서브패스 오버랩 메커니즘 i; 하단: 하위 패스 내 및 하위 패스 간의 데이터 종속성.
Vulkan, Metal, DX12 등 최신 그래픽 API를 사용하면 렌더링 파이프라인 장벽(Barrier)의 대기 단계를 정확하게 지정할 수 있습니다. 예를 들어 다음 그림에서는 기본 PipelineBarrier가 사용되며, 이로 인해 Vertex 및 Fragment 처리에서 더 많은 유휴 또는 대기 시간이 발생하여 GPU 시간 주기가 낭비됩니다.

장벽이 기다려야 하는 소스 및 대상 단계를 수정하면 이러한 유형의 지연이 완화되고 셰이더 유닛의 활용도가 향상될 수 있습니다.

파이프라인 장벽의 구체적인 최적화 예는 다음과 같습니다.

Vulkan의 파이프라인 장벽을 사용하여 각 패스 사이의 대기 단계를 최적화하여 정지와 지연을 줄일 수 있습니다. 그림에서는 28ms에서 22ms로 떨어집니다.
PowerVR의 TBDR 아키텍처는 이 프레임의 모든 픽셀이 비닝 데이터를 처리한 후 렌더링 단계를 시작하므로 더 심각한 지연이 발생할 수 있습니다. 알파 테스트가 켜져 있으면 깊이가 HSR 단계에 다시 기록되므로 HSR의 정상적인 프로세스가 중단되고 예기치 않은 지연이 발생합니다.
최신 GPU(모바일 장치 포함)에는 일반적으로 통합 셰이더 아키텍처가 있습니다. 이 아키텍처의 특징은 모든 셰이더 코어가 VS와 PS를 모두 실행할 수 있다는 것입니다. 미래에는 GS, MS 등이 통합되어 GPU가 VS 또는 PS 집약적인 작업을 조정하고 균등하게 배열할 수 있으므로 모든 코어가 최대한 완전히 로드되어 대기, 유휴 및 지연이 줄어듭니다.

왼쪽: 별도의 셰이더 처리 장치, 오른쪽: 통합 셰이더 처리 장치. 후자의 프로세서는 기본적으로 풀로드에서 실행되므로 대기 및 무부하가 줄어들고 전반적인 컴퓨팅 성능이 향상되는 것을 볼 수 있습니다.
최신 GPU는 SIMD 및 SIMT 기술을 완벽하게 활용하여 전반적인 병렬 효율성과 처리량을 향상시켰습니다.

그러나 GPU 명령 그룹 간에 데이터 종속성이 있는 경우 명령 그룹 간의 실행 시간이 길어집니다.

왼쪽: GPU 명령 그룹이 대기 없이 정상적으로 실행됩니다. 오른쪽: GPU 명령 그룹에 거품이 추가되어 지연이 발생합니다.
위 그림의 거품은 GPU 명령 그룹 간의 데이터 종속성을 해결하기 위해 생성되었습니다.

왼쪽: 다음 명령 세트는 이전 데이터 세트의 쓰기에 따라 달라집니다. 처리하지 않으면 이전 데이터를 얻게 됩니다. 오른쪽: 최신 데이터를 얻을 수 있도록 버블이 다음 명령어 세트에 삽입되고 한 클록 주기만큼 지연됩니다.
Shader의 if 및 for와 같은 동적 분기 루프 문은 GPU 컴퓨팅 장치의 사용률을 줄이고 명령을 실행하는 데 걸리는 시간을 연장합니다.

메모리에 액세스하는 명령으로 인해 GPU 컴퓨팅 장치가 정지되어 계산 시간이 길어집니다.

CPU의 낮은 대기 시간 및 낮은 처리 속도와 달리 GPU는 당연히 높은 병렬성과 높은 처리 속도를 위해 설계되었지만 동시에 캐시 용량이 작고 캐시 적중률이 낮으며 대기 시간이 높습니다.

따라서 GPU 데이터 구조를 제대로 설계하지 않으면 캐시 적중률이 크게 감소하여 컴퓨팅 장치의 지연 및 지연이 증가하게 됩니다. GPU 스레드 스케줄러(Thread Schdule)는 일반적으로 데이터 상관 관계를 고려하고 동일한 스레드 그룹의 스레드를 동일한 캐시 라인에 유지합니다.

사이즈 16의 웨이브 동작 다이어그램. 점선은 스레드 그룹 내 데이터 액세스의 캐시 적중률을 향상시키기 위해 스레드 그룹이 경계를 넘어 데이터에 액세스할 수 없음을 나타냅니다.
위의 상황 외에도 시스템이나 응용 프로그램이 이중 버퍼링, 삼중 버퍼링, 수직 동기화 및 기타 메커니즘을 사용하는 경우 특정 지연도 발생합니다.

3버퍼 실행 메커니즘의 개략도.
Android 시스템 렌더링 모듈은 다단계 캡슐화와 3버퍼 메커니즘을 사용하므로 그림이 항상 3프레임만큼 지연됩니다.


반대로 Async Compute, Copy Engine, Graphic Pipeline 등의 병렬 메커니즘을 잘 활용하고, RDG의 리소스 할당 및 종속성 자동 처리를 사용하고, 하위 리소스 및 별칭 리소스의 특성을 활용하고, 장벽 및 기타 작업을 병합하면 패스 간 및 패스 내 대기 및 지연을 줄이고 병렬 효율성을 향상시킬 수 있습니다.

Async Compute, Copy Engine 및 Graphic Pipeline의 병렬 실행 사례.

리소스 A와 D가 서로 다른 기간에 동일한 메모리 영역을 차지하는 별칭 리소스의 작동 메커니즘에 대한 개략도입니다. 별칭 리소스는 렌더링 시스템에 리소스 관리 복잡성을 추가하더라도 RDG를 사용할 때 사용되는 리소스 할당 공간을 50% 이상 절약할 수 있습니다.
간단히 말해서 CPU 앱 계층의 논리 업데이트부터 렌더링 명령 생성, 그래픽 API 호출 및 제출, 드라이버 계층, 시스템 계층, GPU 내부 및 최종 디스플레이 프레젠테이션 전반에 걸쳐 다양한 종속성, 대기, 정체 및 지연이 있을 수 있습니다. 이를 위해서는 전반적인 상황을 전반적으로 살펴보고, 전체 렌더링 파이프라인의 병목 현상을 식별하고, 올바른 약을 처방하여 프로그램이 모바일 SoC에서 효율적이고 원활하며 즉각적으로 실행될 수 있도록 해야 합니다.
공식 UE4 문서에는 지연 시간에 대한 몇 가지 제안과 최적화 조치가 나와 있습니다. 자세한 내용은 낮은 지연 시간 프레임 동기화를 참조하세요.
- 계속 예정
팀 모집
블로거 팀은 UE4를 사용하여 새로운 몰입형 경험 제품을 개발하고 있으며, 위대한 목표를 달성하기 위해 함께 일하고 협력할 각계각층의 현자들이 시급히 필요합니다. 현재 아래와 같은 직무를 긴급 모집하고 있습니다.
UE 로직 개발.
UE 엔진 프로그램.
UE 그래픽 렌더링.
TA(기술, 예술).
요구사항:
견고한 기술 기반.
기술에 대한 열정이 높습니다.
자기 동기가 좋습니다.
커뮤니케이션 및 협업 능력이 좋은 분.
UE 사용 경험이나 모바일 단말 개발 경험이 있으면 우대합니다.
관심이 있거나 더 알고 싶으시면 블로거의 WeChat 계정을 추가하세요: 81079389(Blog Park에 지원한다고 표시). 또는 이력서를 블로거의 이메일 주소: 81079389#qq.com(#을 @로 바꾸세요)으로 보내주세요.
각계각층의 영웅들이 만나기를 기다립니다.
특별 지침
모든 참고문헌의 저자에게 감사드립니다. 일부 사진은 참고 자료와 인터넷에서 가져온 것이므로 삭제되었습니다.
이 시리즈의 기사는 저자가 직접 작성한 것이며 블로그에만 게시됩니다. 이 글의 링크를 공유하셔도 좋지만 무단 전재는 허용되지 않습니다!
계속되는 일련의 기사. 전체 목록을 보려면 콘텐츠 개요를 클릭하세요.
계속되는 일련의 기사. 전체 목록을 보려면 콘텐츠 개요를 클릭하세요.
계속되는 일련의 기사. 전체 목록을 보려면 콘텐츠 개요를 클릭하세요.
📚 참고 자료 및 공식 링크 (References)
- Unreal Engine Source
- Rendering and Graphics
- Materials
- Graphics Programming
- Mobile Rendering
- Qualcomm® Adreno™ GPU
- PowerVR Developer Documentation
- Arm Mali GPU Best Practices Developer Guide
- Arm Mali GPU Graphics and Gaming Development
- Moving Mobile Graphics
- GDC Vault
- Siggraph Conference Content
- GameDev Best Practices
- Accelerating Mobile XR
- Frequently Asked Questions
- Google Developer Contributes Universal Bandwidth Compression To Freedreno Driver
- Using pipeline barriers efficiently
- Optimized pixel-projected reflections for planar reflectors
- UE4모바일 플랫폼PC 공유 세션
- Deferred Shading in Unity URP
- 📖 모바일 게임 성능 최적화를 위한 일반적인 기법
- 📖 GPU 하드웨어 아키텍처 및 작동 메커니즘에 대한 심층적인 이해
- Adaptive Performance in Call of Duty Mobile
- Jet Set Vulkan : Reflecting on the move to Vulkan
- Vulkan Best Practices - Memory limits with Vulkan on Mali GPUs
- A Year in a Fortnite
- The Challenges of Porting Traha to Vulkan
- L2M - Binding and Format Optimization
- Adreno Best Practices
- GPU아키텍처
- Mali GPU Architectures
- Cyclic Redundancy Check
- Arm Guide for Unreal Engine
- Arm Virtual Reality
- Best Practices for VR on Unreal Engine
- Optimizing Assets for Mobile VR
- Arm® Guide for Unreal Engine 4 Optimizing Mobile Gaming Graphics
- Adaptive Scalable Texture Compression
- Tile-Based Rendering
- Understanding Render Passes
- Lighting for Mobile Platforms
- Frame Pacing for Mobile Devices
- ARM Mali GPU. Midgard Architecture
- ARM’s Mali Midgard Architecture Explored
- [Unite Seoul 2019] Mali GPU Architecture and Mobile Studio
- Killing Pixels - A New Optimization for Shading on ARM Mali GPUs
- Qualcomm's Quad-Core Snapdragon S4 (APQ8064/Adreno 320) Performance Preview
- Low Resolution Z Buffer support on Turnip
- Render Graph 및 API
- Hidden Surface Removal Efficiency
- Unreal Engine 4: Mobile Graphics on ARM CPU and GPU Architecture
- Low Latency Frame Syncing
- Qualcomm® Snapdragon™ Mobile Platform OpenCL General Programming and Optimization
- Qualcomm Announces Snapdragon 865 and 765(G): 5G For All in 2020, All The Details
- Introduction to PowerVR for Developers
- PowerVR Series5 Architecture Guide for Developers
- PowerVR Graphics - Latest Developments and Future Plans
- PowerVR virtualization: a critical feature for automotive GPUs
- PowerVR Performance Recommendations
- PowerVR Low Level GLSL Optimisation
- Mobile GPU approaches to power efficiency
- Processing Architecture for Power Efficiency and Performance
- opengl: glFlush() vs. glFinish()
- Cramming Software onto Mobile GPUs
- Vulkan on Mobile Done Right
- Triple Buffering
- Asynchronous Shaders
- Why Talking About Render Graphs
- NVIDIA Variable Rate Shading
- Introduction to compute shaders
- Introduction to GPU Architecture
- An Introduction to Modern GPU Architecture
- Understanding GPU caches
- Transitioning from OpenGL to Vulkan
- Next Generation OpenGL Becomes Vulkan: Additional Details Released
- Bringing Fortnite to Mobile with Vulkan and OpenGL ES
- Appropriate use of render pass attachments
- Preparing Android for XR