Schedutil
메모
이 모든 것은 빈도와 작업 용량 사이의 선형 관계를 가정하며, 이것이 결함이 있다는 것을 알고 있지만, 작업 가능한 최상의 근사치입니다.
PELT (Per Entity Load Tracking)
PELT를 사용하여 저희는 개별 작업에서 작업 그룹 조각, CPU 런큐에 이르기까지 다양한 스케줄러 엔티티에 걸쳐 몇 가지 메트릭을 추적합니다. 이를 위한 기초로 저희는 지수 가중치 이동 평균(EWMA)을 사용하며, 각 주기(1024us)는 y^32 = 0.5가 되도록 분해됩니다. 즉, 가장 최근의 32ms가 절반을 기여하고 나머지 역사가 나머지 절반을 기여합니다.
Specifically:
ewma_sum(u) := u_0 + u_1*y + u_2*y^2 + ...
ewma(u) = ewma_sum(u) / ewma_sum(1)
이것은 본질적으로 무한 기하급수의 진행이므로 결과는 합성 가능합니다. 즉, ewma(A) + ewma(B) = ewma(A+B)입니다. 이 속성은 작업이 이동할 때 평균을 다시 계산하는 기능을 제공하기 때문에 핵심입니다.
차단된 작업은 여전히 Aggregate(태스크 그룹 슬라이스 및 CPU 실행 대기열)에 기여하며, 이는 해당 작업이 다시 실행될 때 예상되는 기여를 반영합니다.
이를 사용하여 '실행'과 '실행'이라는 두 가지 주요 메트릭을 추적합니다. '실행'은 개체가 CPU에 소비하는 시간을 반영하고 '실행'은 개체가 실행 대기열에 소비하는 시간을 반영합니다. 작업이 하나만 있는 경우 이 두 메트릭은 동일하지만 CPU에 경합이 발생하면 각 작업이 CPU에 소비하는 시간의 비율을 반영하여 '실행'이 감소하고 경합의 양을 반영하여 '실행'이 증가합니다.
For more detail see: kernel/sched/pelt.c
Frequency / CPU Invariance
1GHz에서 50%의 CPU를 사용하는 것은 2GHz에서 50%의 CPU를 사용하는 것과 동일하지 않으며 Little CPU에서 50%를 실행하는 것과 큰 CPU에서 50%를 실행하는 것은 다르기 때문에 아키텍처에서는 DVFS(Dynamic Voltage and Frequency Scaling) 비율과 마이크로아치 비율의 두 가지 비율로 시간 델타를 확장할 수 있습니다.
소프트웨어가 완벽하게 제어되는 단순한 DVFS 아키텍처의 경우 다음과 같이 비율을 계산합니다:
f_cur
r_dvfs := -----
f_max
하드웨어가 DVFS를 제어하는 보다 동적인 시스템의 경우 하드웨어 카운터(Intel APERF/MPERF, ARMv8.4-AMU)를 사용하여 이 비율을 제공합니다. 특히 Intel의 경우 다음을 사용합니다:
APERF
f_cur := ----- * P0
MPERF
4C-turbo; if available and turbo enabled
f_max := { 1C-turbo; if turbo enabled
P0; otherwise
f_cur
r_dvfs := min( 1, ----- )
f_max
당사는 약간 더 지속 가능하도록 1C 터보보다 4C 터보를 선택합니다.
r_cpu는 현재 CPU의 최고 성능 수준 대 시스템의 다른 CPU의 최고 성능 수준의 비율로 결정됩니다.
r_tot = r_dvfs * r_cpu
결과적으로 위의 '실행 중'과 '실행 가능' 메트릭은 DVFS와 CPU 유형의 불변성이 됩니다. IOW. CPU 간에 전송하고 비교할 수 있습니다.
자세한 내용은 다음을 참조하십시오:
- kernel/sched/pelt.h:update_rq_clock_pelt()
- arch/x86/kernel/smpboot.c:"APERF/MPERF frequency ratio computation."
- Capacity Aware Scheduling:"1. CPU Capacity + 2. Task utilization"
UTIL_EST / UTIL_EST_FASTUP
주기적인 작업은 수면 중에 평균이 감소하기 때문에 예상 활용률이 동일하더라도 다시 실행한 후에는 DVFS(Ramp-up)가 증가합니다.
이를 완화하기 위해(기본 활성화 옵션) ULTY_EST는 디큐가 가장 높을 때 '실행 중' 값을 가진 IIR(Infinite Impulse Response) EWMA를 구동합니다. 추가 기본 활성화 옵션 ULTY_EST_FASTUP은 IIR 필터를 즉시 증가시키고 감소 시에만 감소하도록 수정합니다.
실행 가능한 태스크의 추가 실행 대기열 전체 합계는 다음과 같이 유지됩니다:
util_est := Sum_t max ( t_running, t_util_est_ewma )
자세한 내용은 kernel/sched/fair.c:util_est_dequeue()를 참조하십시오
UCLAMP
각 CFS 또는 RT 작업에 유효한 u_min 및 u_max 클램프를 설정할 수 있습니다. 실행 대기열은 모든 실행 작업에 대해 이러한 클램프의 최대 집합을 유지합니다.
For more detail see: include/uapi/linux/sched/types.h
Schedutil / DVFS
스케줄러 로드 트래킹이 업데이트될 때마다(태스크 웨이크업, 태스크 마이그레이션, 시간 진행) 하드웨어 DVFS 상태를 업데이트하기 위해 스케줄러로 호출합니다.
기본은 CPU 런큐의 '실행 중' 메트릭이며, 이 메트릭은 위에서 CPU의 주파수 불변 사용률 추정치입니다. 이를 통해 다음과 같이 원하는 주파수를 계산합니다:
max( running, util_est ); if UTIL_EST
u_cfs := { running; otherwise
clamp( u_cfs + u_rt , u_min, u_max ); if UCLAMP_TASK
u_clamp := { u_cfs + u_rt; otherwise
u := u_clamp + u_irq + u_dl; [approx. see source for more detail]
f_des := min( f_max, 1.25 u * f_max )
XXX IO-wait: IO 완료로 인한 작업 웨이크업으로 인해 업데이트가 완료되면 위에서 'u'를 부팅합니다.
그런 다음 이 주파수를 사용하여 P-state/OPP를 선택하거나 하드웨어에 대한 CPPC 스타일 요청에 직접 녹입니다.
XXX: 마감 작업(Sporadic Task Model)을 통해 작업량을 충족하는 데 필요한 하드 f_min을 계산할 수 있습니다.
이러한 콜백은 스케줄러에서 직접 가져온 것이므로 DVFS 하드웨어 상호 작용은 '빠르고' 비차단 상태여야 합니다. Schedutil은 하드웨어 상호 작용이 느리고 비용이 많이 드는 경우에 대한 속도 제한 DVFS 요청을 지원하므로 효율성이 떨어집니다.
For more information see: kernel/sched/cpufreq_schedutil.c
NOTES
DVFS가 가장 관련성이 높은 저부하 시나리오에서는 '실행 중' 수치가 활용률을 밀접하게 반영합니다.
포화 시나리오에서 작업 이동으로 인해 일시적인 감소가 발생할 수 있습니다. CPU가 4개의 작업으로 포화되었다고 가정하고 작업을 유휴 CPU로 마이그레이션할 때 이전 CPU의 '실행 중' 값은 0.75가 되고 새 CPU는 0.25가 됩니다. 이는 피할 수 없는 일이며 시간 경과가 이를 수정할 것입니다. XXX는 유휴 시간이 없으므로 여전히 f_max를 보장합니까?
위의 대부분은 DVFS 감소를 방지하는 것이며, 로드 시프트 시 독립적인 DVFS 도메인을 재학습/램프업해야 합니다.
참고 문헌