STAT STREAMING
콘솔 명령으로 텍스처 스트리밍 통계를 프로파일링할 수 있습니다. 이 명령은 텍스처 스트리머가 사용하는 성능, 메모리 사용량 등의 지표를 보고합니다.
STAT STREAMING sortby=name maxhistoryframes=1
메모리 데이터를 읽을 때 등장하는 ‘풀(pool)'이라는 용어는 개념적(예약된) 메모리를 나타내며, 실제로 차지하는 메모리와는 관련이 없습니다. ‘밉(mips)'이라는 단어는 예상 사용량이나 미래의 사용량이 아니라 현재 텍스처가 사용하는 메모리입니다. 메모리 지표는 크게 세 가지 풀로 분류됩니다.
텍스처(Texture)
스트리밍(Streaming)
원티드(Wanted)
풀의 크기는 메모리 카운터(Memory Counters) 카테고리의 각 줄 오른쪽에 표시됩니다.
통계 |
설명 |
---|---|
사이클 카운터 |
|
Game Thread Update Time |
게임 스레드 업데이트 시간 - 스트리머 업데이트 함수에 소요된 시간입니다. 텍스처 스트리밍 작업의 대부분을 차지합니다. 텍스처, 컴포넌트, 레벨의 레퍼런스 삭제를 비롯한 일부 작업만 텍스처 스트리머 외부에서 처리됩니다. 게임 스레드 업데이트를 진행하는 동안 스트리머는 전체 업데이트가 되기까지 하나의 단계를 수행합니다. 전체 업데이트는 여러 프레임을 필요로 하며, `r.Streaming.FramesForFullUpdate`와 연관되어 있습니다. 다양한 업데이트 단계는 통계의 **카운터(Counter)** 섹션에 정의되어 있습니다. |
메모리 카운터 |
|
Texture Pool |
텍스처 풀 - 텍스처 리소스에 사용할 수 있는 총 메모리입니다. 여기에는 렌더 타깃, GPU 파티클 버퍼, 큐브 맵, UI 텍스처, 스트리밍 불가 텍스처와 같은 비스트리밍 리소스가 포함됩니다. 일부 플랫폼에서는 스태틱 메시와 같은 비텍스처 리소스를 저장하는 데 이 메모리를 사용할 수도 있습니다. 텍스처 풀(Texture Pool) 은 대략적으로 안전 풀(Safety Pool) + 임시 풀(Temporary Pool) + 스트리밍 풀(Streaming Pool) + 비스트리밍 밉(NonStreaming Mips) 과 동일합니다(변동이 존재한다면 최대 안전 풀 크기입니다). |
Safety Pool |
안전 풀 - 이 값은 |
Temporary Pool |
임시 풀 - 이 값은 `r.Streaming.MaxTempMemoryAllowed`로 제어하며, 텍스처 크기 조절 시 스트리머가 사용할 수 있는 추가 메모리를 지정합니다. 텍스처의 밉 수를 변경하는 경우 엔진은 더 크거나 작은 새 텍스처를 생성해야 하며, 이곳에 앞으로의 밉 데이터가 저장됩니다. 이 과정이 들어오는 요청의 양을 간접적으로 제어하게 되는데, 스트리머가 임시 풀이 허용하는 한도 내에서 최대한 많은 요청을 IO 시스템으로 전송하기 때문입니다. 텍스처 풀은 적어도 스트리밍할 가장 큰 리소스만큼 커야 하지만, 너무 크게 설정하면 메모리가(그 목적으로만 예약되므로) 낭비됩니다. 반면 너무 작게 설정하면(IO 시스템을 위해 충분한 작업을 만들어내지 못하므로 시스템이 대기 상태가 되어) 스트리밍 속도가 떨어질 수 있습니다. 또한, 스트리머는 들어오는 요청의 처리 순서를 제어하는 능력이 떨어집니다. 다시 말해, 상대적으로 작은 임시 풀을 사용하면 처음 로드되는 대상을 보다 잘 통제할 수 있습니다. |
Streaming Pool |
스트리밍 풀 - 텍스처 스트리머가 사용할 수 있는 메모리 양입니다. 스트리머는 보통 새로운 밉을 스트리밍하거나 기존의 스트리밍된 밉을 메모리에 최대한 오래 유지하는 데 가용 메모리 전부를 사용합니다. 스트리밍 풀에는 보이는 밉(Visible Mips), 숨겨진 밉(Hidden Mips), 강제 밉(Force Mips), 캐시된 밉(Cached Mips)이 포함됩니다. 스트리밍 풀 은 대략적으로 보이는 밉(Visible Mips) + 숨겨진 밉(Hidden Mips) + 강제 밉(Forced Mips) + 캐시된 밉(Cached Mips) 과 같습니다(*: 전부 사용된 경우이며, 그렇지 않으면 미사용 공간을 고려해야 합니다). |
NonStreaming Mips |
비스트리밍 밉 - 비스트리밍 할당에 사용되는 메모리의 양입니다. 이 할당이 정기적으로 안전 풀의 값보다 크게 변동하는 경우 스트리밍 풀 예산이 영향을 받기 때문에 (할당을 줄이거나 안전 풀을 키워) 큰 변동을 피해야 합니다. |
Required Pool |
필수 풀 - 텍스처 스트리머가 지표에 따라 로드해야 할 밉 데이터 양입니다. 이 값은 텍스처 스트리밍 풀의 100%를 초과할 수 있습니다. 이 경우 약간의 절충이 이루어지므로 일부 텍스처는 필수 해상도로 로드되지 않습니다. |
Visible Mips |
보이는 밉 - 보이는 텍스처 밉이 현재 차지하는 원티드 메모리입니다. 강제 밉은 포함되지 않습니다. |
Hidden Mips |
숨겨진 밉 - 보이지 않는 텍스처 밉이 현재 차지하는 원티드 메모리입니다. 강제 밉은 포함되지 않습니다. 텍스처를 처음 표시할 때 저해상도 텍스처가 보이는 것을 방지하기 위해 스트리머는 보통 필요한 것보다 하나 적은 밉으로 미리 텍스처를 스트리밍합니다( |
Forced Mips |
강제 밉 - 강제로 스트림 인된 텍스처가 현재 차지하는 원티드 메모리입니다. 텍스처는 보통 짧은 기간 게임플레이 메커니즘을 통해 강제로 스트림 인됩니다. 스트리밍 불가(non-streamable)로 플래그 설정된 텍스처는 포함되지 않습니다. |
Cached Mips |
캐시된 밉 - 더 이상 필요하지 않은 텍스처 밉이 차지하는 메모리입니다. 다른 원티드 밉에 메모리가 필요하지 않다면 캐시에 유지됩니다. |
Wanted Pool |
원티드 풀 - 결국 스트림 인될 필수 풀의 일부입니다. |
Wanted Mips |
원티드 밉 - 실제로 스트림 인되는 원티드 풀의 양입니다. 100%에 도달하면 스트리머는 새로운 밉 로드를 위한 IO 요청 전송을 중지합니다. 원티드 밉(Wanted Mips) 은 보이는 맵(Visible Mips) + 숨겨진 맵(Hidden Mips) + 강제 맵(Forced Mips) 과 같습니다. |
Inflight Requests |
들어오는 요청 - IO가 계속해서 처리해야 하는 메모리 양입니다. 0일 경우, 모든 기존 요청이 새 요청 생성 시 처리된 것입니다. 스트리머가 콘텐츠를 스트리밍할 때 이런 일이 발생할 경우 스트리머가 사용 가능한 대역폭을 전부 사용하지 않고 있다는 의미입니다. |
IO Bandwidth |
IO 대역폭 - 마지막 업데이트 이후 완료된 밉 로드 크기를 마지막 업데이트 이후 시간으로 나눈 값입니다. 이 값은 정확한 IO 대역폭 측정값은 아니지만 시스템이 요청을 로드하는 속도를 파악하는 데 사용될 수 있습니다. |
카운터 |
|
Setup Async Task |
비동기 작업 구성 - 비동기 스트리머 작업에 대한 데이터를 준비하는 데 걸리는 시간입니다. 전체 업데이트 루프의 첫 단계로 실행됩니다. |
Update Streaming Data |
스트리밍 데이터 업데이트 - 스트리밍 데이터를 점증적으로 업데이트하는 데 걸리는 시간입니다. 비저빌리티 새로고침, 텍스처 상태 업데이트, 사용된 다이내믹 컴포넌트의 바운드 업데이트 등을 포함합니다. 이 단계는 `r.Streaming.FramesForFullUpdate`에 정의된 것처럼 연속으로 여러 프레임에 걸쳐 실행됩니다. |
Streaming Texture |
스트리밍 텍스처 - 로드 및 취소 요청을 준비하고 전송하는 데 걸리는 시간입니다. |
새로 로드되는 레벨의 점증적 처리
언리얼 엔진 4.15 부터 텍스처 스트리머는 레벨 데이터를 로드 시점과 눈에 보이게 되는 시점 사이에 점증적으로 각 프레임마다 조금씩 처리합니다. 이전에는 레벨이 눈에 보이게 되는 프레임에 이 과정이 이루어졌기 때문에 버벅임이 느껴지기도 했습니다.
프레임마다 처리되는 작업량은 `r.Streaming.NumStaticComponentsProcessedPerFrame`으로 제어하며, 기본값은 50 입니다. 이 값을 **0** 으로 설정하면 점증적 방식이 비활성화되어 시스템이 4.15 이전 방식으로 작동하게 됩니다.
중요한 것은 점증적 레벨 처리는 모빌리티가 스태틱 설정된 컴포넌트에만 적용된다는 점입니다. 무버블 컴포넌트는 항상 엔진 틱에서 점증적 처리됩니다.
점증적 처리가 완료되면 레벨이 보이기 전까지 더 이상의 처리가 필요하지 않습니다. 점증적 처리가 완료되기 전에 레벨이 보이게 되면 대기 중인 모든 작업을 즉시 완료해야 하므로 약간의 버벅임이 생길 수 있습니다.
다음은 점증적 처리를 검사하는 콘솔 명령입니다.
Stat Streaming SortBy=name
비용은 Update Streaming Data 카테고리에 포함됩니다.
퍼포먼스
아래 정보는 4.15에서 향상된 텍스처 스트리머의 개선 목표와 구체적인 개선 지표를 나타낸 것입니다.
텍스처 스트리머가 차지하는 텍스처 수 감소
이 개선사항은 컴포넌트별 비저빌리티 처리를 통해 이루어졌습니다. 보이지 않거나 숨겨진 컴포넌트에 사용되는 텍스처는 프리페치로 밉을 하나 낮춰 스트리밍합니다. 또한, 머티리얼별 텍스처 스트리밍 데이터를 추가하여 디테일 맵 등의 경우 UV 채널에 적용된 스케일을 올바르게 계산할 수 있습니다.
마지막으로, 나머지 개선사항은 스태틱 지오메트리에 대한 (비교적 작은) 머티리얼별 바운드의 계산입니다.
아래는 레벨에서 세 가지 시점을 사용하는 파라곤에서 얻은 지표입니다.
필수 텍스처 풀 |
이전 |
이후 |
보이는 양 |
---|---|---|---|
스타트업 |
678 MB |
564 MB |
370 MB |
맵 사이드 레인 |
796 MB |
597 MB |
308 MB |
맵 미들 레인 |
1086 MB |
674 MB |
271 MB |
보이는 텍스처의 스트림 인 시간 감소
(글로벌 텍스처 예산 감소와 별도로)보이는 텍스처를 스트림 인하는 데 걸리는 시간을 줄이기 위해 스트리머는 예산이 설정된 밉 대비 보이는 밉의 표를 유지합니다. 예산이 설정된 밉 중에서 보이는 밉을 추적함으로써 스트리머는 프리페치 및 강제 로드 데이터를 스트림 인하기 전에 감지 가능 데이터를 스트림 인 할 수 있습니다.
아래는 레벨에서 세 가지 시점을 사용하는 파라곤에서 얻은 지표입니다.
보이는 밉 로드 |
이전 |
이후 |
---|---|---|
스타트업 |
20s |
10s |
맵 사이드 레인 |
19s |
9s |
맵 미들 레인 |
20s |
6s |
스트리머가 차지하는 CPU 시간 감소
다이내믹 컴포넌트 처리를 비동기 텍스처 스트리밍 작업으로 이동하여 CPU 시간을 향상했습니다. 과예산 상황 처리, 텍스처 로드 순서 결정 등 다른 작업도 이동되었습니다.
아래의 예시는 최악의 파라곤 업데이트 프레임의 개선사항을 나타냅니다.
게임 스레드 업데이트 비용 |
이전 |
이후 |
---|---|---|
최악의 업데이트 프레임 |
1.1 ms |
0.6 ms |
이와 관련된 또 다른 주요 개선사항은 레벨이 로드되었지만 아직 보이지 않는 상황에서 새로 로드된 레벨 스트리밍 데이터를 점증적으로 처리하는 기능입니다.
게임 스레드 레벨 로드 비용 |
이전 |
이후 |
---|---|---|
점증적 업데이트 |
150 ms |
3 ms |
로우 퀄리티 및 악성 행동 제거
메시 UV 밀도는 메시 단위가 아닌 머티리얼 단위로 계산됩니다. 이 새로운 데이터는 LOD도 고려합니다. 이로 인해 텍스처가 저해상도로 나타나는 대부분의 문제가 해결되었습니다.
또한 파티클 시스템, 인스턴스드 메시를 포함해 컴포넌트에서 더욱 폭넓은 텍스처 스트리밍이 지원됩니다. 이는 기타 저해상도 문제를 해결해주고, 경우에 따라 높은 메모리 소모량 문제도 처리해줍니다.
다양한 메모리 예산별 수동 미세조정 제거
텍스처 스트리머는 번거로운 수동 미세조정 없이 다양한 메모리 예산을 자동으로 맞출 수 있습니다. 스트리머는 시각적 악영향을 최소화하고자 다양한 휴리스틱 기법을 사용해 줄여야 하는 텍스처를 선택합니다.
최소한의 텍스처만 영향을 받게 되고, 그 영향 또한 한 곳에 집중되기 때문에 위치에 따라 희생 내용이 달라집니다.