Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

오디오를 지연시키는 요인

이 페이지에서는 출력 지연 시간의 요인에 집중하지만, 유사한 내용이 입력 지연 시간에도 적용됩니다.

아날로그 회로가 크게 기여하지 않는다고 가정한다면 오디오 지연 시간에 대한 표면적인 수준의 주요 요인은 다음과 같습니다.

  • 애플리케이션
  • 파이프라인의 총 버퍼 수
  • 각 버퍼의 크기(프레임)
  • DSP 등의 앱 프로세서 이후의 추가적인 지연 시간

위의 요인은 정확한 만큼이나 오해의 소지도 있습니다. 이유는 버퍼 수와 버퍼 크기가 원인보다는 효과에 가깝기 때문입니다. 주어진 버퍼 체계에서 일어나는 상황은 구현 및 테스트를 거치지만 테스트 도중에는 오디오 언더런이나 오버런이 '딸깍'하는 소리나 터지는 소리로 들립니다. 그러면 시스템 설계자는 이를 보완하기 위해 버퍼 크기나 버퍼 수를 늘립니다. 이 경우 언더런이나 오버런을 제거하여 원하는 결과를 얻을 수 있지만 지연 시간 증가라는 부작용으로 이어질 수도 있습니다. 버퍼 크기에 대한 자세한 내용은 오디오 지연 시간: 버퍼 크기 동영상을 참조하세요.

더 좋은 접근 방식은 언더런과 오버런의 원인을 이해한 다음 이를 수정하는 것입니다. 그러면 오디오 아티팩트가 제거되고 더 작고 적은 수의 버퍼를 허용하여 지연 시간을 줄일 수 있습니다.

경험에 의해 확인된 언더런과 오버런의 가장 일반적인 원인은 다음과 같습니다.

  • Linux CFS(Completely Fair Scheduler)
  • SCHED_FIFO 스케줄링을 포함하는 높은 우선순위의 스레드
  • 우선순위 역전
  • 긴 스케줄링 지연 시간
  • 오래 실행되는 인터럽트 핸들러
  • 긴 인터럽트 금지 시간
  • 전력 관리
  • 보안 커널

Linux CFS 및 SCHED_FIFO 스케줄링

Linux CFS는 범용 CPU 리소스를 공유하는 경쟁 워크로드에 공정하도록 설계되었습니다. 이러한 공정성은 스레드당 nice 매개변수로 표현됩니다. nice 값의 범위는 -19(nice가 가장 적거나 가장 많은 CPU 시간이 할당됨)~20(nice가 최대이거나 가장 적은 CPU 시간이 할당됨)입니다. 일반적으로 주어진 nice 값을 포함하는 모든 스레드는 대략적으로 동일한 CPU 시간과 스레드를 얻으며, 수치적으로 낮은 nice 값은 더 많은 CPU 시간을 얻습니다. 하지만 CFS는 상대적으로 긴 관찰 시간에 대해서만 '공정'합니다. 짧은 관찰 기간에 대해서는 CFS가 예상치 못한 방식으로 CPU 리소스를 할당할 수 있습니다. 예를 들면 CPU를 nice가 수치적으로 적은 스레드에서 nice가 수치적으로 높은 스레드로 옮길 수 있습니다. 오디오의 경우에는 언더런이나 오버런의 결과로 이어질 수도 있습니다.

확실한 해결책은 고성능 오디오 스레드에 CFS의 사용을 피하는 것입니다. Android 4.1부터는 이러한 스레드에 CFS에 의해 구현된 SCHED_NORMAL(SCHED_OTHER이라고도 불림) 스케줄링 정책 대신 SCHED_FIFO 스케줄링 정책이 사용됩니다.

SCHED_FIFO 우선순위

이제는 고성능 오디오 스레드에 SCHED_FIFO가 사용되지만, 그럼에도 우선순위가 높은 다른 SCHED_FIFO 스레드의 영향을 받을 수 있습니다. 이는 커널 작업자 스레드인 경우가 일반적이지만, 정책 SCHED_FIFO를 포함하는 몇 개의 비오디오 사용자 스레드일 수도 있습니다. 가용한 SCHED_FIFO 우선순위 범위는 1~99입니다. 오디오 스레드는 우선순위 2 또는 3에서 실행됩니다. 결과적으로는 우선순위 1을 우선순위가 낮은 스레드에, 우선순위 4~99를를 높은 수준의 스레드에 사용할 수 있습니다. 가능한 한 우선순위 1을 사용하고, 우선순위 4~99는 귀속된 시간 내에 100% 완료되고 오디오 스레드 기간보다 짧은 기간으로 실행되고 오디오 스레드의 스케줄링을 방해하지 않는 것으로 알려진 스레드를 위해 남겨 놓는 것이 좋습니다.

비율 단조 스케줄링

고정된 우선순위 할당 이론에 대한 자세한 내용은 Wikipedia 문서, 비율 단조 스케줄링(RMS)을 참조하세요. 핵심 요점은 인지된 '중요성'이 아닌 기간을 기준으로만 고정된 우선순위를 할당해야 하며, 높은 우선순위는 짧은 기간의 스레드에 할당해야 한다는 것입니다. 비주기적 스레드는 실행의 최대 주파수와 실행당 최대 계산을 사용하여 주기적인 스레드로 모델링할 수 있습니다. 비주기적 스레드를 주기적 스레드로 모델링할 수 없는 경우(예: 실행당 무제한 주파수 또는 무제한 계산으로 실행될 수 있음)에는 고정된 우선순위를 할당하면 안 됩니다. 이는 순수한 주기적 스레드의 스케줄링과 호환되지 않기 때문입니다.

우선순위 역전

우선순위 역전은 실시간 시스템의 전형적인 고장 모드입니다. 여기서는 우선순위가 더 낮은 작업이 mutex에 의해 보호되는 공유 상태와 같은 리소스를 방출할 때까지 기다리기 위한 무한 시간에 대해 우선순위가 높은 작업이 차단됩니다. 이를 완화하는 방법은 문서, '우선순위 역전 회피'를 참조하세요.

스케줄링 지연 시간

스케줄링 지연 시간은 스레드 실행 준비가 완료된 시점부터 스레드가 실제로 CPU에서 실행될 수 있도록 결과적인 문맥 전환이 완료되는 시점까지의 시간입니다. 지연 시간은 짧을수록 좋으며, 2밀리초보다 길 경우 오디오 문제의 원인이 됩니다. 긴 스케줄링 지연 시간은 CPU를 가동 또는 종료하거나 보안 커널과 일반 커널 간에 전환하거나 전출력에서 저출력 모드로 전환하거나 CPU 클록 주파수 및 전압을 조정하는 등의 모드 전환 도중에 발생할 가능성이 가장 높습니다.

인터럽트

다수의 설계에서는 CPU 0이 모든 외부 인터럽트를 처리합니다. 따라서 오래 실행되는 인터럽트 핸들러가 다른 인터럽트를 지연시킬 수 있으며, 특히 오디오 DMA(직접 메모리 접근) 완료 인터럽트의 경우 지연 가능성이 더 높습니다. 인터럽트 핸들러가 빠르게 작업을 마무리하고 긴 작업을 스레드(CFS 스레드 또는 우선순위 1의 SCHED_FIFO 스레드 권장)에 미루도록 설계하세요.

마찬가지로 장시간 동안 CPU 0에 대한 인터럽트를 금지할 경우 오디오 인터럽트 처리를 지연시키는 동일한 결과를 지닙니다. 긴 인터럽트 금지 시간은 보통 커널 스핀락을 기다리는 동안 발생합니다. 이러한 스핀락에 한계가 있는지 검토하세요.

전력, 성능 및 열 관리

전력 관리는 성능 최적화 도중의 전력 소모 모니터링 및 절감을 위한 노력을 포괄하는 광범위한 용어입니다. 열 관리컴퓨터 냉각은 서로 유사하지만 열을 측정하고 제어하여 과열에 의한 손상을 피하도록 합니다. Linux 커널에서는 CPU 거버너가 저수위 정책을 담당하는 반면 사용자 모드에서는 고수준 정책을 구성합니다. 사용되는 기술은 다음과 같습니다.

  • 동적 전압 조정
  • 동적 주파수 조정
  • 동적 코어 지원
  • 클러스터 전환
  • 파워게이팅
  • 핫플러그(핫스왑)
  • 다양한 절전 모드(중지, 중단, 유휴, 일시정지 등)
  • 프로세스 이전
  • 프로세서 어피니티

일부 관리 작업은 '작업 중단'이나 애플리케이션 프로세서에 의해 유용한 작업이 수행되지 않는 시간으로 이어질 수 있습니다. 이러한 작업 중단은 오디오를 방해할 수 있으므로 이러한 관리는 오디오 활성 상태에서 용인되는 최악의 작업 중단에 대해 설계되어야 합니다. 물론 열폭주가 임박한 경우에는 영구적 피해를 피하는 것이 오디오보다 중요합니다.

보안 커널

디지털 권한 관리를 위한 보안 커널이 같은 애플리케이션 프로세서 코어에서 기본 운영체제 커널 및 애플리케이션 코드에 사용되는 커널로 실행될 수 있습니다. 보안 커널 작업이 코어에 대해 활성화된 시간은 해당 코어에서 일반적으로 실행되는 일반 작업의 중단이라고 보면 됩니다. 특히 여기에는 오디오 작업이 포함될 수 있습니다. 특성적으로 보안 커널의 내부 동작은 높은 수준의 계층에서 불가해합니다. 따라서 보안 커널에 의한 모든 성능 이상은 특히 치명적입니다. 예를 들어 보안 커널 작업은 문맥 전환 흔적에 나타나지 않는 것이 일반적입니다. 우리는 이를 경과되지만 관찰할 수는 없는 '다크 타임'이라고 부릅니다. 보안 커널은 오디오 활성 상태에서 용인되는 최악의 작업 중단에 대해 설계되어야 합니다.