용량은 일정 시간 동안 기기가 보유한 일부 리소스(CPU, GPU 등)의 총량입니다. 이 페이지에서는 용량 관련 버벅거림 문제를 식별하고 해결하는 방법을 설명합니다.
거버너의 반응이 느림
버벅거림을 피하려면 CPU 주파수 거버너가 갑작스러운 워크로드에 빠르게 대응할 수 있어야 합니다. 대부분의 UI 애플리케이션은 다음과 같이 동일한 기본 패턴을 따릅니다.
- 사용자가 화면을 읽는 중입니다.
- 사용자가 버튼을 탭하거나 스크롤하는 등 화면을 터치합니다.
- 사용자의 입력에 반응해 화면이 스크롤되거나, 화면에서 활동이 변경되거나, 애니메이션이 적용됩니다.
- 새 콘텐츠가 표시될 때에는 시스템이 잠시 중지됩니다.
- 사용자가 화면 읽기로 돌아갑니다.
Pixel 및 Nexus 기기는 터치 시 CPU 주파수 거버너(및 스케줄러) 동작을 수정하기 위해 터치 부스트를 구현합니다. 높은 클록 주파수까지 느리게 증가하는 것을 피하기 위해(이 속도가 느리면 터치 시 프레임이 누락될 수 있음) 터치 부스트는 일반적으로 CPU의 주파수 하한값을 설정하여 터치 시 사용할 수 있는 충분한 CPU 용량을 확보합니다. 터치 후 최젓값은 일정 시간 동안 지속됩니다(일반적으로 약 2초).
Pixel은 EAS(에너지 인식 스케줄링)에서 제공하는 schedtune cgroup을 추가 터치 부스트 신호로 사용합니다. 상위 애플리케이션은 schedtune을 통해 추가 가중치를 받아 빠른 실행에 충분한 CPU 용량을 확보합니다. Nexus 5X와 6P는 Kryo CPU를 탑재한 Pixel보다 크고 빅 CPU 클러스터와 리틀 CPU 클러스터(각각 A53 및 A57) 간 성능 차이가 훨씬 큽니다. 특히 기기의 다른 잡음 소스를 고려할 때 리틀 CPU 클러스터가 매끄러운 UI 렌더링에 항상 적합한 것은 아닙니다.
따라서 Nexus 5X 및 6P에서 터치 부스트는 스케줄러 동작을 수정하여 포그라운드 애플리케이션이 빅 코어로 이동할 가능성을 높입니다. 이는 CPU 주파수에서의 최젓값과 개념적으로 유사합니다. 포그라운드 애플리케이션이 빅 CPU 클러스터로 이동할 가능성이 더 커지도록 스케줄러를 변경하지 않으면 스케줄러에서 스레드를 빅 CPU 코어로 부하 분산을 처리하도록 결정할 때까지 포그라운드 애플리케이션은 렌더링할 CPU 용량이 부족할 수 있습니다. 터치 부스트 중 스케줄러 동작을 변경하면 UI 스레드가 빅 코어에서 즉시 실행되고 버벅거림을 피할 가능성이 커지지만 큰 항상 빅 코어에서 실행되도록 강제하지 않으므로 전력 소비에 큰 영향을 미칠 수 있습니다.
열 조절
열 조절은 전반적인 열 출력을 줄여야 할 때 발생하며, 일반적으로 CPU, GPU, DRAM 클록을 줄여 실행됩니다. 당연한 이야기지만, 시스템이 지정된 타임슬라이스 내에서 렌더링할 수 있는 충분한 용량을 더 이상 제공할 수 없으므로 종종 버벅거림이 발생합니다. 열 조절을 피하는 유일한 방법은 전력 소모를 줄이는 것입니다. 전력 소모를 줄이는 방법은 많지 않지만 과거의 SOC 관련 경험을 바탕으로 시스템 공급업체를 위한 몇 가지 권장사항이 있습니다.
첫째, 이기종 CPU 아키텍처를 사용하여 새 SOC를 빌드할 때 CPU 클러스터의 성능/W 곡선이 겹치는지 확인합니다. 전체 프로세서의 전반적인 성능/W 곡선은 연속된 선이 되어야 합니다. 성능/W 곡선에 연속되지 않는 부분이 있으면 스케줄러와 주파수 거버너에게 워크로드가 필요한 항목을 추측해야 합니다. 버벅거림을 방지하기 위해 스케줄러 및 주파수 거버너는 필요한 용량보다 지나치다 싶을 정도로 많은 워크로드를 제공하게 됩니다. 이로 인해 과도한 전력이 소모되고, 이는 열 조절에 기여합니다.
CPU 클러스터 2개가 있는 가상 SOC가 있다고 생각해 보겠습니다.
- 클러스터 1은 리틀 클러스터로, 100~300mW를 소비하고 클록에 따라 처리량 업계 기준치에서 100~300점을 받고 있습니다.
- 클러스터 2는 빅 클러스터로, 1,000~1,600mW를 소비하고 클록에 따라 동일한 처리량 업계 기준치에서 800~1,200점을 받고 있습니다.
이 업계 기준치에서는 점수가 높을수록 속도가 더 빠른 것입니다. 속도가 느린 것보다 더 바람직하다고 할 수는 없지만 속도가 빠르면 소비 전력이 더 많아집니다.
스케줄러가 UI 워크로드에 처리량 업계 기준치의 310점과 동등한 용량이 필요하다고 판단한 경우 버벅거림을 피하기 위한 최상의 옵션은 가장 낮은 주파수에서 빅 클러스터를 실행하는 것인데, 이 경우 상당한 전력이 소모됩니다. 이는 cpuidle 동작과 유휴 상태의 경합에 따라 달라지며, 연속 성능/W 곡선이 있는 SOC는 더 쉽게 최적화할 수 있습니다.
둘째, cpuset를 사용합니다. 커널과 BoardConfig.mk
에서 cpuset를 사용 설정했는지 확인합니다. 또한 기기별 init.rc
에서 실제 cpset 할당을 설정해야 합니다. 다른 힌트를 사용해 스케줄러 동작에 영향을 미칠 수 있기를 기대하면서 BSP에서 cpuset를 사용 중지 상태로 두는 공급업체도 있는데, 바람직한 방법은 아닙니다. cpuset는 CPU 간 부하 분산이 사용자가 기기에서 실제로 실행하는 작업을 반영하는 방식으로 이루어지도록 하는 데 유용합니다.
ActivityManager는 중요도가 높은 애플리케이션의 CPU 코어의 액세스 가능성을 높이면서 앱의 상대적 중요도(상위, 포그라운드, 백그라운드)에 따라 다른 cpuset에 앱을 할당합니다. 이렇게 하면 포그라운드 및 상위 앱의 서비스 품질을 보장할 수 있습니다.
cpuset는 동종 CPU 구성에서는 유용하지만 cpuset를 사용 설정하지 않은 상태에서는 CPU 구성이 다른 기기를 제공하면 안 됩니다. Nexus 6P는 이기종 CPU 구성에서 cpuset를 사용하는 방법을 보여주는 훌륭한 모델로, 이 모델을 기기 구성의 기준으로 삼을 수 있습니다.
cpuset는 성능이 중요하지 않은 백그라운드 스레드가 빅 CPU 코어에 부하 분산되지 않도록 하여 전력상의 이점을 제공합니다. 이러한 스레드가 빅 코어로 부하 분산되면 사용자에게 피부로 와 닿는 이점 없이 전략 소비량만 크게 늘어날 수 있습니다. 이렇게 되면 열 조절도 피할 수 있습니다. 열 조절은 용량 문제이지만 잡음을 개선하면 열 조절 시 UI 성능에 큰 영향을 미칩니다. 시스템이 60FPS를 렌더링하는 기능에 더 가깝게 실행되므로 잡음이 줄어 프레임 누락이 발생합니다.