버전

menu_open
Wwise SDK 2019.1.11
I/O 도움말, 문제 해결 및 최적화
Default Streaming Manager Information

이번 장에 설명된 도움말 및 그 밖에 I/O와 관련한 고려 사항들은 고급 Stream Manager API의 기본 구현을 사용하며 자신의 I/O 코드를 Low-Level I/O 인터페이스 아래 연결하는 경우에만 해당됩니다. 이번 장에 나온 내용의 대부분이 기본 Stream Manger 설정(Audiokinetic Stream Manager 초기화 설정)과 Low-Level I/O 인터페이스(Low-Level I/O)에 대해 숙지했다는 가정 하에 설명되었습니다.

Setting Up a DVD Device

기본 장치 설정(AK::StreamMgr::GetDefaultDeviceSettings에서 가져옴)은 DVD 장치에 적합합니다. 기본 단위가 16 KB지만, 단위가 더 커지면 종종 단일 스트림의 DVD 정보 처리량이 더 많아집니다. 대부분의 DVD 드라이브에는 32 KB이면 적절합니다. 오디오 파일을 한 두 개 이상 스트리밍할 일이 절대 없을 경우에만 더 큰 세분성을 사용하세요. 그렇지 않을 경우, 다른 것 대신 단일 스트림의 처리량을 최적화합니다. 또한, 세분성이 클 수록 더 많은 스트림 I/O 메모리를 필요로 한다는 점에 유의하세요.

어느 시점에서는 메모리 사용을 최적화할 필요가 생길 것입니다. 이와 관련한 유용한 정보는 I/O 풀 메모리 사용 줄이기 를 참고하세요.

차단 I/O 후크 대신 지연 I/O 후크 사용하기

차단 I/O 후크 대신 지연 I/O 후크를 사용하는 것은 일반적으로 덜 효율적인 방법입니다. 그 이유는, 지연 I/O 장치가 잘못된 예측을 좀 더 많이 하기 때문이며 (취소된 전송을 만들어내거나 대역폭을 낭비함), Stream Manager 풀에서 메모리를 더 많이 사용하기 때문입니다. 다음 상황에 처했을 경우에만 지연 I/O 후크를 사용하세요.

게임 엔진 I/O 관리자가 비동기 API를 노출

자신의 I/O 관리자가 비동기 API만 표시하는데 여기로 Wwise I/O 호출을 라우팅하려고 할 때, 지연 I/O 후크로 어댑터 레이어를 구현하는 것이 훨씬 쉽습니다. 자주 발생하는 지연 I/O 장치의 잘못된 예측을 줄이기 위해서는 AkDeviceSettings::uMaxConcurrentIO 를 1이나 2로 설정합니다.

게임 엔진 I/O 관리자가 파일 배치에 따라 I/O 요청을 뒤 봐꿈

Wwise Stream Manager는 디스크에서 파일이 물리적으로 어디에 위치할지 결정을 내릴 수 없습니다. 자신의 I/O 관리자가, 예를 들어 파일 배치를 스스로 알고 바로 옆에 가까이 있는 전송을 고려하며 보류 중인 요청의 순서를 뒤 바꿀 수 있다면, Wwise Stream Manager로부터 한번에 더 많은 전송을 받는 것이 나을 수 있습니다.

전송 완료가 발생된 전송 개수로부터 독립적일 때

일부 장치는 발행된 전송의 개수와 큰 상관이 없이 전송 요청을 주기적으로 해결합니다. 주로 DMA 제어기 기반의 장치들에서 이러한 방식이 사용됩니다. DMA가 완료될 때 전송도 완료되지만, 다음 DMA를 준비하기 전까지 완료되기를 기다리지 않으려면 큰 값의 AkDeviceSettings::uMaxConcurrentIO 로 지연 장치를 사용하세요. 이 때 충분히 큰 값을 사용해 Low-Level I/O로 전송되는 I/O 요청을 막지 않도록 합니다. 따라서 대역폭의 양은 오직 대상 버퍼링 길이에 의해서만 통제됩니다.

여러 개의 장치 사용하기

일반적으로 각각의 물리적 장치(DVD, HDD, RAM/VRAM, 등)에 대해 서로 다른 스트리밍 장치를 따로따로 사용해야 합니다. 첫 번째 이유는, 스트리밍 장치가 각각 별개의 스레드에서 실행되기 때문입니다. 이는, 전송 요청이 물리적 장치들 사이에서 병렬화되는 것을 원치 않을 경우 의무사항입니다. HDD 읽기를 발행하기 전에 DVD 읽기를 기다린다면 매우 비효율적일 것입니다. 두 번째 이유는, 대부분의 경우 최적화 설정이 각 장치별로 다르기 때문입니다.

여러 개의 장치를 사용할 경우, 발송자가 필요합니다. 여러 장치로 시스템을 구현하는 방법에 대한 더 자세한 정보는 다중 장치 I/O 시스템 를 참고하세요.

발송을 위해서는 어느 장치에서 어느 파일을 열 것인지 알아야 합니다. 이 때 파일 패키지를 사용할 것을 추천합니다. 사운드뱅크를 생성한 후 File Packager를 이용해 사운드뱅크와 스트리밍된 오디오 파일을 다양한 파일 패키지에 함께 묶을 수 있습니다. 각 파일 패키지는 특정 장치에서 로드되도록 고안되었습니다. 런타임에서 간단한 발송자는 파일 여는 것을 수락하는 장치가 나올 때까지 장치를 하나씩 쿼리할 수 있습니다. 이것이 기본 발송자의 역할입니다 (SDK 예제에서 AkDefaultLowLevelIODispatcher.h/cpp 참고). 이 방법으로 대체 매커니즘을 구현할 수도 있습니다. 예를 들어, RAM/VRAM 장치로부터 파일 하나를 로드해보고, 만약 로드되지 않으면 DVD에서 로드합니다.

파일 발송과 장치 할당이 동시에 이뤄져야 한다는 점에 유의하세요. 지연이 불가능하므로 빠르게 진행될 수 있도록 주의하도록 합니다. SDK 예제에 구현된 파일 패키지 검색은 바이너리 검색 알고리즘을 사용하기 때문에 매우 빠릅니다.

I/O 문제 해결

Wwise 툴을 자신의 게임에 연결하고 프로파일러를 이용해 자신의 I/O 시스템과 설정을 최적화하고 문제를 해결합니다. Capture Log는 음원 고갈 및 기타 I/O 오류들을 알려줍니다. Advanced Profiler 뷰에 있는 Streams 탭과 Streaming Devices 탭은 온전히 I/O 전용입니다.

또한, AkFileDescAK::StreamMgr::IAkLowLevelIOHook::GetDeviceDesc(), AK::StreamMgr::IAkLowLevelIOHook::GetDeviceData() 의 커스텀 매개 변수를 사용해 자신의 하위 레벨 I/O 시스템 데이터 일부를 Wwise 프로파일러에 표시할 수도 있습니다.

음원 고갈 문제 해결

음원 (I/O) 고갈은 스트리밍 데이터가 요청한 시간 안에 Stream Manager로 발송되지 않았을 때 발생합니다. 프로파일러의 Capture Log에 고갈된 오디오 음원의 이름/ID와 함께 오류 알림이 뜹니다.

음원 고갈의 원인

잘못된 I/O 설정 때문이 아니라 다른 원인으로도 음원 고갈이 발생할 수 있습니다.

1) 상호작용 음악: Interactive Music 계층 구조의 오브젝트의 스트리밍은 미리 예약해야 하며 스트리밍 데이터가 필요한 시간에 맞춰 준비돼있어야 합니다. 이 예견 시간은 각 뮤직 트랙의 속성입니다. 상호작용 음악을 사용할 때 고갈이 발생했다면, 사용자가 지정해놓은 예견 시간이 충분하지 않기 때문일 수 있습니다.

2) 레이턴시 없는 스트리밍: 사운드와 음악 트랙 속성에서 'Zero Latency' 옵션을 체크할 경우, 스트리밍 파일의 시작 부분이 사운드뱅크로 저장됩니다. 이를 재생하기 위해 이벤트를 발송하면, 사운드뱅크에 저장돼있던 데이터(프리페치된 데이터)를 이용해 곧바로 재생됩니다. 그러나 해당 파일의 뒷부분이 디스크로부터 스트리밍되기 전에 프리페치된 데이터를 모두 소진할 경우 음원 고갈이 발생합니다. 이런 경우 프리페치 길이를 늘려줍니다.

'Zero-Latency' 체크가 돼있지 않은 Actor-Mixer Hierarchy의 사운드는 대상 버퍼링 길이에 도달하기 전에는 절대 재생을 시작하지 않습니다. 목표 버퍼링에 도달하는 시간은 사운드의 최초 레이턴시로 구성돼있습니다. 따라서 만약 이 사운드에 고갈이 발생하면, 잘못되거나 불균형한 I/O 상태가 원인일 확률이 높습니다.

I/O 메모리 부족

장치가 제공하는 것보다 더 많은 처리량을 요구하는 것 외에, 고갈의 주된 요인은 I/O 메모리 부족입니다. I/O 메모리 풀이 꽉 차면 스트리밍 장치가 하위 레벨 I/O에 보내던 전송 요청을 멈춥니다. 프로파일러의 Streaming Devices 탭에서 I/O 메모리 사용량을 확인하세요.

과도한 작업량

어떤 상황에서 음원 고갈이 발생되고, 특정 스트림을 이용하지 않은 경우, 자신의 I/O 장치에 비해 너무 많은 오디오 데이터를 요청하고 있기 때문일 수 있습니다. 다른 게임 에셋과 대역폭을 공유해야한다는 점을 잊지 마세요. I/O에서 오디오 부담을 제한하는 방법으로는, 인스턴스 제한이나 가상 보이스와 같이 Wwise에서 데이터 기반 기능을 사용하는 스트림의 숫자를 제한하는 방법을 추천합니다.

대상 버퍼링이 너무 작을 때에도 고갈이 발생할 수 있습니다. Streams 탭에서 Buffering Status와 참조된 메모리(Ref. Memory)의 양을 주의 깊게 살펴보세요. 위젯에 주로 'full'이 뜨면서 참조된 메모리가 자주 0으로 떨어진다면, 대상 버퍼링이 너무 작아서 그럴 수 있습니다. 즉, I/O 스레드가 대부분 idle이지만, I/O 스케줄러가 I/O 요청을 발송하려고 할 때 디스크로부터 버퍼를 읽어오는 시간을 채우기에는 버퍼링이 부족한 것입니다.

반면, 변한 없는 상태를 유지해야 하는 스트리밍(즉, 이미 재생이 시작된 경우)에 대해 Buffering Status 위젯이 'not full'을 나타내면 하위 레벨 I/O 장치가 스트리밍에 비해 너무 느리다는 뜻입니다. I/O 풀에 더 이상 사용할 메모리가 없을 경우나(Streaming Devices 탭을 확인하세요), 스케줄러가 동시 I/O 요청 개수를 AkDeviceSettings::uMaxConcurrentIO 아래로 떨어질 때까지 기다리고 있는 경우도 고갈의 원인이 될 수 있습니다.

특정 스트림에 대해서 체계적으로 발생하는 고갈

때로는 음원 고갈이 특정 스트림에 대해서만 체계적으로 발생하는 경우가 있습니다.

하나의 스트리밍 장치에서 모든 오디오 스트림을 올바르게 처리하는 데 필요한 총 처리량은, 압축 형식, 샘플 레이트, 채널 수, 등에 기반한 휴리스틱을 이용해 스트림 간 균형을 유지합니다. 그러나 일부 변수 비트레이트 코덱(XMA나 Vorbis)은 빠른 탐색 도중이나 반복 재생 경계점에서 최초 선언한 I/O 데이터를 더 필요로하는 경우가 있습니다. 만약 탐색 도중에 이러한 일이 발생할 경우, 변환 설정(conversion settings)에서 빠른 이동 테이블(seek table) 블록 크기를 좀더 작게 사용해보세요. 빠른 이동은 상호작용 음악과 'From Elapsed Time' 가상 보이스 작동 방식에서도 발생합니다.

또는, 디스크에서 멀리 떨어져 있는 파일에 의해서도 발생할 수 있습니다. 플랫폼의 툴을 이용해 (파일 패키지 사용시 File Packager 유틸리티 이용) 런타임에 발생하는 탐색을 최소화하여 디스크 상의 파일 배치를 최적화하세요.

또는, 대상 버퍼링 길이를 늘려 이러한 처리량 요구가 갑자기 치솟는 현상을 보완할 수 있습니다 (단, 증가하는 I/O 메모리 사용량에 주의).

그 밖의 도움말

If you stream small looping sounds, it may be useful to enable caching (AkDeviceSettings::fMaxCacheRatio). 이렇게 하면 대역폭과 I/O 메모리를 절약할 수 있습니다.

또한, DVD/HDD 장치를 사용할 때 대역폭을 낭비하지 않도록 주의합니다. 지연 장치를 사용할 경우, 취소된 전송에 유의합니다 (프로파일러의 Streaming Devices 탭). 동시 전송의 최대 개수를 줄이면 도움이 될 수 있습니다 (AkDeviceSettings::uMaxConcurrentIO).

Reducing I/O 스레드로 CPU 사용량 줄이기

I/O 장치의 스레드는 대부분의 경우 I/O를 기다리고 있기 때문에 CPU 사용률이 크지 않은 편입니다. 이러한 CPU 사용은 RAM 장치와 같이 매우 빠른 장치에서 더 주의해야 합니다. 이러한 경우, 다음과 같이 조치할 수 있습니다.

  • 대상 버퍼링 감소시키기
  • 스레드 우선순위 낮추기

만약 CPU가 치솟는 현상이 파일을 열 때 발생한다면, 파일을 여는 작업에 많은 시간이 소요되는 것이 이유일 수 있습니다. 일부 플랫폼/디스크 장치는 fopen()의 반환 값을 구하는 게 매우 느립니다. 이런 경우, 파일 열기를 지연시키세요 ( 지연 열기 에서 자세한 내용 참고).

I/O 풀 메모리 사용 줄이기

동시 재생되고 있는 스트리밍의 개수를 줄이는 것 외에, 다음과 같은 방법으로 사용할 I/O 메모리 크기를 줄일 수 있습니다.

  • 세분성 낮추기 (장치 처리량에 끼칠 부정적 영향에 주의)
  • 대상 버퍼링 낮추기 (음원 고갈에 주의)
  • 스트림 데이터 캐시 사용하기 (반면, 캐시는 작은 풀에서는 그다지 효율적이지 않음)

I/O 메모리 풀에서는 단편화가 절대 발생하지 않습니다. 또한, 이 풀에서 가끔 발생하는 메모리 고갈은 크게 지장을 주지 않습니다. 보통의 경우, 이미 스트리밍되어 들어온 데이터는 이렇게 메모리 사용이 치솟는 현상을 충분히 견딜 수 있습니다. 가장 안 좋은 시나리오는 음원 고갈이 발생하는 것입니다.

Stream Manager 풀 메모리 사용 줄이기

Stream Manager 메모리 풀은 작은 오브젝트 할당에 사용됩니다. 장치 및 스트림 오브젝트, 전송 구조체, 비동기 파일 열기 저장, 스트림 메모리 조회 테이블, 등이 여기에 해당됩니다. 일반적으로 이 풀에 필요한 크기는 꽤 작은 편이지만, 이 풀에서 메모리가 고갈되지 않도록 주의하는 편이 좋습니다. 만약 메모리가 고갈되면 복구 불가능한 I/O 실패가 발생합니다. 대부분 장치가 생성될 때 할당된다는 점에 유의하세요.

다음 설정을 사용하면 Stream Manager 풀에 필요한 메모리를 줄일 수 있습니다.

  • 지연 장치 대신 차단 장치를 사용.
  • 지연 장치를 사용하면 동시 요청 최대 개수를 줄일 수 있습니다 (AkDeviceSettings::uMaxConcurrentIO).
  • Decrease the cache ratio (AkDeviceSettings::fMaxCacheRatio);
  • 동기 파일 열기 실행 ( 지연 열기 에서 자세한 내용 참고)
  • 동시에 열리는 스트림 개수 제한

이 페이지가 도움이 되었나요?

지원이 필요하신가요?

질문이 있으신가요? 문제를 겪고 계신가요? 더 많은 정보가 필요하신가요? 저희에게 문의해주시면 도와드리겠습니다!

지원 페이지를 방문해 주세요

작업하는 프로젝트에 대해 알려주세요. 언제든지 도와드릴 준비가 되어 있습니다.

프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.

Wwise를 시작해 보세요