scheduler

Utilization Clamping

jsh91 2023. 11. 28. 00:37

1. Introduction

Util clamp 또는 uclamp라고도 알려진 Util clamp는 사용자 공간을 사용하여 작업의 성능 요구 사항을 관리하는 데 도움을 주는 스케줄러 기능입니다. 이 기능은 v5.3 릴리스에서 도입되었습니다. CG그룹 지원은 v5.4에서 병합되었습니다.

Uclamp는 작업의 성능 요구사항과 제한사항을 스케줄러가 이해할 수 있는 힌트 메커니즘이므로 스케줄러가 더 나은 결정을 내릴 수 있도록 도와줍니다. 그리고 schedutil cpufreq governor를 사용하면 util clamp는 CPU 주파수 선택에도 영향을 미칩니다.

스케줄러와 스케줄러는 모두 PELT(util_avg) 신호에 의해 구동되기 때문에 Util 클램프는 신호를 특정 지점으로 클램핑하여 목표를 달성하기 위해 작동하므로 이름이 붙여집니다. 즉, 클램핑 활용을 통해 시스템을 특정 성능 지점에서 작동시키도록 합니다.

Util clamp를 보는 올바른 방법은 성능 제약 조건에 대한 요청을 하거나 힌트를 주는 메커니즘입니다. 두 개의 변수로 구성됩니다:

  • UCLAMP_MIN, which sets the lower bound.
  • UCLAMP_MAX, which sets the upper bound.

이 두 가지 경계는 작업이 시스템의 이 성능 범위 내에서 작동하도록 보장합니다. UCLAMP_MIN은 작업의 부팅을 의미하는 반면 UCLAMP_MAX는 작업의 캡핑을 의미합니다.

원하는 사용자 경험을 전달하기 위해 일부 작업은 작동하기 위한 최소한의 성능 포인트가 필요하다고 시스템(스케줄러)에 말할 수 있습니다. 또는 일부 작업은 리소스를 너무 많이 소비하는 것이 제한되어야 하며 특정 성능 포인트를 초과해서는 안 된다고 시스템에 말할 수 있습니다. UCLAMP 값을 활용도가 아닌 성능 포인트로 보는 것이 사용자 공간 관점에서 더 나은 추상화입니다.

예를 들어, 게임은 인지된 초당 프레임 수(FPS)와 피드백 루프를 형성하기 위해 유틸리티 클램프를 사용할 수 있습니다. 이는 프레임이 손실되지 않도록 보장하기 위해 디스플레이 파이프라인에 필요한 최소 성능 지점을 동적으로 증가시킬 수 있습니다. 또한 이는 향후 수백 밀리초 내에 계산 집약적인 장면이 발생할 것이라는 것을 알 경우 이러한 작업을 동적으로 '프라임'할 수 있습니다.

장치의 성능이 매우 다양한 모바일 하드웨어에서 이 동적 피드백 루프는 모든 시스템의 기능을 고려할 때 최상의 사용자 환경을 보장하는 뛰어난 유연성을 제공합니다.

물론 정적 구성도 가능합니다. 정확한 사용법은 시스템, 애플리케이션 및 원하는 결과에 따라 달라집니다.

또 다른 예는 안드로이드에서 작업이 백그라운드, 포그라운드, 탑 앱 등으로 분류되는 경우입니다. Util clamp를 사용하여 백그라운드 작업이 실행할 수 있는 성능 포인트를 캡핑하여 리소스 소비량을 제한할 수 있습니다. 이 제약 조건은 현재 활성화된 앱(탑 앱 그룹)에 속하는 작업과 같은 중요한 작업에 대한 리소스를 예약하는 데 도움이 됩니다. 이 외에도 전력 소비량을 제한하는 데 도움이 됩니다. 이기종 시스템(예: Arm big.Little)에서는 이러한 제약 조건이 백그라운드 작업이 작은 코어에 유지되도록 편향하는 데 도움이 됩니다:

 

1. 빅 코어는 상위 앱 작업을 즉시 자유롭게 실행할 수 있습니다. 상위 앱 작업은 사용자가 현재 상호 작용하고 있는 작업이므로 시스템에서 가장 중요한 작업입니다.

2. CPU 집약적인 작업이라 하더라도 전력이 부족한 코어에서 실행되지 않고 배터리가 방전됩니다.

Note

little cores:

CPUs with capacity < 1024

big cores:

CPUs with capacity = 1024

 

이러한 uclamp 성능 요청 또는 힌트를 제공함으로써 사용자 공간은 시스템 리소스가 가능한 최상의 사용자 환경을 제공하기 위해 최적으로 사용되도록 보장할 수 있습니다.

또 다른 사용 사례는 스케줄러 활용 신호가 계산되는 방법에서 램프 업 지연 시간 상속을 극복하는 데 도움이 됩니다.

반면, 최대 성능 지점에서 실행해야 하는 바쁜 작업은 스케줄러가 이를 인식하는 데 ~200ms(PELT HALFIFE = 32ms)의 지연이 발생합니다. 이는 모바일 장치의 게임과 같은 워크로드에 영향을 미치며, 응답 시간이 느려져 작업이 제 시간에 완료되는 데 필요한 더 높은 빈도를 선택할 수 있습니다. UCLAMP_MIN = 1024를 설정하면 이러한 작업이 실행되기 시작할 때 항상 가장 높은 성능 수준을 확인할 수 있습니다.

전체적인 가시 효과는 더 잘 인식되는 사용자 경험/성능을 넘어 효과적으로 사용할 경우 전체 성능/와트를 더 잘 달성할 수 있도록 도와줍니다.

사용자 공간은 열 서브시스템과 피드백 루프를 형성하여 장치가 조절할 지점까지 가열되지 않도록 할 수도 있습니다.

SCHED_NORMAL/OTHER 및 SCHED_FIFO/RR 모두 uclamp 요청/힌트를 준수합니다.

SCHED_FIFO/RR의 경우 uclamp는 항상 MAX 주파수에 얽매이지 않고 어떤 성능 지점에서든 RT 작업을 실행할 수 있는 옵션을 제공합니다. 이는 배터리로 구동되는 장치에서 실행되는 범용 시스템에서 유용할 수 있습니다.

RT 작업은 설계에 따라 작업별 PELT 신호가 없으며 불확실한 DVFS 램프업 지연을 방지하기 위해 항상 일정한 주파수로 실행되어야 합니다.

주의할 점은 RT 작업이 깨어날 때 schedutil을 사용하면 주파수를 수정하는 데 항상 한 번의 지연이 발생한다는 것입니다. 이 비용은 uclamp를 사용하면 변경되지 않습니다. Uclamp는 모든 RT 작업에 대해 항상 MAX를 요청하는 대신 요청할 주파수를 선택하는 데 도움이 됩니다.

기본값은 섹션 3.4를 참조하고 RT 작업 기본값을 변경하는 방법은 섹션 3.4.1을 참조하십시오.

 

2. Design

Util 클램프는 시스템의 모든 작업의 속성입니다. 사용 신호의 경계를 설정하고 스케줄러 내의 특정 결정에 영향을 미치는 바이어스 메커니즘 역할을 합니다.

실제로는 작업의 실제 활용 신호가 클램핑 되지 않습니다. 어느 시점에서든지 PELT 신호를 검사하면 그대로 계속 봐야 합니다. 클램핑은 필요할 때만 일어나는데, 예를 들어 어떤 작업이 실행되기 위해서는 스케줄러가 적절한 CPU를 선택해야 합니다.

유틸리티 클램프의 목표는 작업을 실행하기 위해 최소 및 최대 성능 포인트를 요청하는 것이기 때문에 작업 배치뿐만 아니라 주파수 선택에도 영향을 미칠 수 있어야 합니다. 이 둘은 CPU 런큐(rq의 줄임말) 수준의 활용도 값에 영향을 미치며, 이는 우리에게 주요 설계 과제를 안겨줍니다.

작업이 rq에서 깨어날 때, rq의 사용 신호는 그 작업에 큐잉된 모든 작업의 uclamp 설정에 영향을 받습니다. 예를 들어, 작업이 ULT_MIN = 512에서 실행되도록 요청할 경우, rq의 사용 신호는 큐잉된 모든 작업의 다른 요청뿐만 아니라 이 요청을 존중해야 합니다.

rq에 연결된 모든 작업의 Util clamp 값을 집계하려면 uclamp가 스케줄러 핫 경로인 모든 대기열/디큐에서 하우스키핑을 수행해야 합니다. 따라서 속도가 느려지면 많은 사용 사례에 큰 영향을 미치고 실제로 사용성이 저하될 수 있으므로 주의해야 합니다.

이를 처리하는 방법은 사용률 범위를 버킷(structuclamp_bucket)으로 나누는 것으로, 검색 공간을 rq의 모든 작업에서 최상위 버킷의 일부 작업으로만 줄일 수 있습니다.

작업이 대기열에 오르면 일치 버킷의 카운터가 증가하고 디큐에서는 감소합니다. 이를 통해 rq 레벨에서 유효 uclamp 값을 추적하는 것이 훨씬 쉬워집니다.

 

작업이 대기열과 대기열을 해제할 때, 우리는 rq의 현재 유효 uclamp 값을 추적합니다. 이것의 작동 방식에 대한 자세한 내용은 섹션 2.1을 참조하십시오.

나중에 rq의 유효 uclamp 값을 확인하려는 경로에서는 결정을 내리는 데 필요한 정확한 순간에 rq의 유효 uclamp 값을 읽기만 하면 됩니다.

현재는 EAS/CAS(Energy Aware Scheduling)와 용량 인식 스케줄링(Capacity Aware Scheduling)만 uclamp를 사용하므로 이기종 시스템에서만 적용됩니다. 작업이 시작되면 스케줄러는 모든 rq의 현재 유효 uclamp 값을 보고 작업을 수행할 경우 해당 작업을 새 값과 비교합니다. 가장 에너지 효율적인 조합으로 끝나는 rq를 선호합니다.

마찬가지로, 스케쥴틸에서는 주파수 업데이트가 필요할 때 현재 거기에 입력된 일련의 작업에 의해 영향을 받는 rq의 현재 유효 uclamp 값을 보고 요청에서 제약 조건을 충족할 적절한 주파수를 선택합니다.

과사용 상태 설정(EAS를 효과적으로 비활성화하는)과 같은 다른 경로도 uCLAMP를 사용합니다. 이러한 경우는 위의 두 가지 주요 사용 사례를 허용하는 데 필요한 하우스키핑으로 간주되며 구현 세부 정보에 따라 변경될 수 있으므로 여기에서는 자세히 다루지 않습니다.

 

2.1. Buckets

                         [struct rq]

(bottom)                                                    (top)

  0                                                          1024
  |                                                           |
  +-----------+-----------+-----------+----   ----+-----------+
  |  Bucket 0 |  Bucket 1 |  Bucket 2 |    ...    |  Bucket N |
  +-----------+-----------+-----------+----   ----+-----------+
     :           :                                   :
     +- p0       +- p3                               +- p4
     :                                               :
     +- p1                                           +- p5
     :
     +- p2

 

Note

The diagram above is an illustration rather than a true depiction of the internal data structure.

 

작업이 큐/디큐될 때 rq의 유효 uclamp 값을 결정하려고 할 때 검색 공간을 줄이기 위해 전체 사용 범위는 COFIG_UCLAMP_BUCKETS_COUNT를 설정하여 컴파일 시간에 N이 구성된 N개의 버킷으로 구분됩니다. 기본적으로 5로 설정됩니다.

rq에는 [UCLAMP_MIN, UCLAMP_MAX]의 각 uCLAMP_id 테이블에 대한 버킷이 있습니다.

각 버킷의 범위는 1024/N입니다. 예를 들어 기본값인 5의 경우 5개의 버킷이 있으며 각 버킷은 다음 범위를 포함합니다:

 

DELTA = round_closest(1024/5) = 204.8 = 205

Bucket 0: [0:204]
Bucket 1: [205:409]
Bucket 2: [410:614]
Bucket 3: [615:819]
Bucket 4: [820:1024]

When a task p with following tunable parameters

p->uclamp[UCLAMP_MIN] = 300
p->uclamp[UCLAMP_MAX] = 1024

rq에 대기열에 추가되면 버킷 1은 UCLAMP_MIN에 대해 증가하고 버킷 4는 UCLAMP_MAX에 대해 증가하여 rq에 이 범위의 작업이 있다는 사실을 반영합니다.

그런 다음 rq는 각 uclamp_id에 대한 현재 유효 uclamp 값을 추적합니다.

작업 p가 대기열에 추가되면 rq 값은 다음과 같이 변경됩니다.

// update bucket logic goes here
rq->uclamp[UCLAMP_MIN] = max(rq->uclamp[UCLAMP_MIN], p->uclamp[UCLAMP_MIN])
// repeat for UCLAMP_MAX

마찬가지로 p가 디큐되면 rq 값은 다음과 같이 바뀝니다:

// update bucket logic goes here
rq->uclamp[UCLAMP_MIN] = search_top_bucket_for_highest_value()
// repeat for UCLAMP_MAX

모든 버킷이 비어 있으면 rqlamp 값이 시스템 기본값으로 재설정됩니다. 기본값에 대한 자세한 내용은 섹션 3.4를 참조하십시오.

 

2.2. Max aggregation

Util 클램프는 최고 성능 지점이 필요한 작업에 대한 요청을 충족하도록 조정됩니다.

여러 개의 작업이 동일한 rq에 연결되어 있는 경우, Util 클램프는 필요하지 않거나 이 지점에 도달할 수 없는 다른 작업이 있더라도 가장 높은 성능의 지점이 필요한 작업이 이 지점에 도달하는지 확인해야 합니다.

예를 들어 다음 값을 가진 rq에 여러 작업이 연결된 경우:

p0->uclamp[UCLAMP_MIN] = 300
p0->uclamp[UCLAMP_MAX] = 900

p1->uclamp[UCLAMP_MIN] = 500
p1->uclamp[UCLAMP_MAX] = 500

 

그러면 p0과 p1이 모두 동일한 rq로 큐잉된다고 가정하면 UCLAMP_MIN과 UCLAMP_MAX는 모두 다음과 같이 됩니다:

rq->uclamp[UCLAMP_MIN] = max(300, 500) = 500
rq->uclamp[UCLAMP_MAX] = max(900, 500) = 900

 

섹션 5.1에서 볼 수 있듯이, 이 최대 집계는 사용자 공간이 전력을 절약하고자 할 때 특히 UCLAMP_MAX 힌트를 위해 사용자 클램프를 사용할 때 제한 사항 중 하나의 원인입니다.

 

2.3. Hierarchical aggregation

앞에서 언급했듯이, util clamp는 시스템의 모든 작업의 속성입니다. 그러나 실제 적용되는 (유효한) 값은 작업 또는 작업을 대신하는 다른 행위자(middleware library)가 요청하는 것 이상으로 영향을 받을 수 있습니다.

모든 작업의 유효 유틸리티 클램프 값은 다음과 같이 제한됩니다:

1. cgroup CPU 컨트롤러에 의해 정의된 uclamp 설정에 의해 연결됩니다(있는 경우).
2. 그러면 (1)의 제한된 값은 시스템 전체 u클램프 설정에 의해 추가로 제한됩니다.

 

3절에서는 인터페이스에 대해 논의하고 이에 대해 더 자세히 설명합니다.

지금은 태스크가 요청을 할 경우 실제 유효 값은 c그룹 및 시스템 전체 설정에 의해 부과되는 몇 가지 제한 사항을 준수해야 한다는 것으로 충분합니다.

시스템은 사실상 제약 조건을 벗어나더라도 요청을 수락하지만 작업이 다른 cgroup으로 이동하거나 sysadmin이 시스템 설정을 수정하는 즉시 요청이 새로운 제약 조건 내에 있는 경우에만 요청이 충족됩니다.

즉, 이 집계는 작업이 uclamp 값을 변경할 때 오류를 발생시키는 것이 아니라 시스템이 이러한 요인을 기반으로 요청을 충족하지 못할 수 있습니다.

 

2.4. Range

UCLAMP 성능 요청의 범위는 0~1024입니다.

cgroup 인터페이스 백분율을 사용합니다(0 ~ 100 포함). 다른 cgroup 인터페이스와 마찬가지로 100 대신 'max'를 사용할 수 있습니다.

 

3. Interfaces

3.1. Per task interface

sched_setattr () syscall이 두 개의 새 필드를 허용하도록 확장되었습니다:
 

  • sched_util_min: 이 작업이 실행 중일 때 시스템이 실행해야 할 최소 성능 지점을 요청하거나 성능 경계를 낮춥니다.
  • sched_util_max: 이 작업이 실행 중일 때 시스템이 실행해야 할 최대 성능 지점을 요청합니다. 또는 상위 성능 경계입니다.

예를 들어, 다음과 같은 시나리오에는 40%에서 80%의 활용률 제약이 있습니다:

attr->sched_util_min = 40% * 1024;
attr->sched_util_max = 80% * 1024;

 

태스크 @p가 실행 중일 때 스케줄러는 40% 성능 수준에서 시작할 수 있도록 최선을 다해야 합니다. 태스크가 충분히 오래 실행되어 실제 활용도가 80% 이상이 되면 활용도, 즉 성능 수준이 제한됩니다.

특수 값 -1은 u클램프 설정을 시스템 기본값으로 재설정하는 데 사용됩니다.

-1을 사용하여 uclamp 값을 시스템 기본값으로 재설정하는 것은 uclamp 값을 수동으로 시스템 기본값으로 설정하는 것과 동일하지 않습니다. 이 구분은 시스템 인터페이스에서 보게 되겠지만 RT의 기본값이 변경될 수 있기 때문에 중요합니다. SCHED_NORMAL/OTHER도 나중에 비슷한 노브를 얻을 수 있습니다.

 

3.2. cgroup interface

CPU cgroup 컨트롤러에는 두 가지 uclamp 관련 값이 있습니다:

  • cpu.uclamp.min
  • cpu.uclamp.max

태스크가 CPU 컨트롤러에 연결되면 해당 uclamp 값은 다음과 같이 영향을 받습니다:

  • cpu.uclamp.min은 cgroup v2 설명서의 섹션 3-3에 설명된 보호 기능입니다.
    작업 uclamp_min 값이 cpu.uclamp.min 값보다 작으면 작업은 cgroup cpu.uclamp.min 값을 상속합니다.
    그룹 계층 구조에서 유효 cpu.uclamp.min은 (하위, 상위)의 최대값입니다.
  • cpu.uclamp.max는 cgroup v2 설명서의 섹션 3-2에 설명된 제한입니다.
    작업 uclamp_max 값이 cpu.uclamp.max보다 높으면 작업은 cgroup cpu.uclamp.max 값을 상속합니다.
    그룹 계층 구조에서 유효한 cpu.uclamp.max는 (자녀, 부모)의 최소값입니다.

For example, given following parameters:

p0->uclamp[UCLAMP_MIN] = // system default;
p0->uclamp[UCLAMP_MAX] = // system default;

p1->uclamp[UCLAMP_MIN] = 40% * 1024;
p1->uclamp[UCLAMP_MAX] = 50% * 1024;

cgroup0->cpu.uclamp.min = 20% * 1024;
cgroup0->cpu.uclamp.max = 60% * 1024;

cgroup1->cpu.uclamp.min = 60% * 1024;
cgroup1->cpu.uclamp.max = 100% * 1024;

 

p0과 p1이 cgroup0에 붙어 있을 때 값은 다음과 같습니다:

p0->uclamp[UCLAMP_MIN] = cgroup0->cpu.uclamp.min = 20% * 1024;
p0->uclamp[UCLAMP_MAX] = cgroup0->cpu.uclamp.max = 60% * 1024;

p1->uclamp[UCLAMP_MIN] = 40% * 1024; // intact
p1->uclamp[UCLAMP_MAX] = 50% * 1024; // intact

 

p0과 p1이 cgroup1에 붙어 있으면 대신 다음과 같이 됩니다:

p0->uclamp[UCLAMP_MIN] = cgroup1->cpu.uclamp.min = 60% * 1024;
p0->uclamp[UCLAMP_MAX] = cgroup1->cpu.uclamp.max = 100% * 1024;

p1->uclamp[UCLAMP_MIN] = cgroup1->cpu.uclamp.min = 60% * 1024;
p1->uclamp[UCLAMP_MAX] = 50% * 1024; // intact

cgroup 인터페이스는 cpu.uclamp.max 값이 cpu.uclamp.min보다 낮도록 허용합니다. 다른 인터페이스에서는 이를 허용하지 않습니다.

 

3.3. System interface

3.3.1 sched_util_clamp_min

허용된 UCLAMP_MIN 범위의 시스템 전체 제한입니다. 기본적으로 1024로 설정되어 있으며, 이는 태스크에 대해 허용된 유효 UCLAMP_MIN 범위가 [0:1024]임을 의미합니다. 예를 들어 512로 변경하면 범위가 [0:512]로 줄어듭니다. 이는 획득할 수 있는 부스팅 태스크의 양을 제한하는 데 유용합니다.

이 노브 값을 초과하는 작업의 요청은 여전히 성공하지만 p->uclamp[UCLAMP_MIN] 이상이 될 때까지 충족되지 않습니다.

 

3.3.2 sched_util_clamp_max

허용된 UCLAMP_MAX 범위의 시스템 전체 제한. 기본적으로 1024로 설정되어 있으며, 이는 작업에 대해 허용된 유효 UCLAMP_MAX 범위가 [0:1024]임을 의미합니다.

예를 들어 512로 변경하면 유효 허용 범위가 [0:512]로 줄어듭니다. 즉, 512를 초과하는 작업은 수행할 수 없으므로 모든 rq도 제한됩니다. IOW는 전체 시스템의 성능 용량이 절반으로 제한됩니다.

이는 시스템의 전체 최대 성능 지점을 제한하는 데 유용합니다. 예를 들어, 배터리가 부족할 때 또는 유휴 상태에 있거나 화면이 꺼져 있을 때 시스템이 더 많은 에너지가 부족한 성능 수준으로 액세스를 제한하려는 경우 성능을 제한하는 데 유용할 수 있습니다.

이 노브 값을 초과하는 작업의 요청은 여전히 성공하지만 p->uclamp[UCLAMP_MAX] 이상이 될 때까지 충족되지 않습니다.

값은 sched_util_clamp_min보다 크거나 같아야 합니다.

 

3.4. Default values

기본적으로 모든 SCHED_NORMAL/SCHED_OTHER 작업은 다음 작업으로 초기화됩니다:

p_fair->uclamp[UCLAMP_MIN] = 0
p_fair->uclamp[UCLAMP_MAX] = 1024

즉, 기본적으로 부팅 시 또는 런타임 시 변경된 최대 성능 지점에서 실행되도록 부스트됩니다. 이것을 제공해야 하는 이유에 대해서는 아직 논의되지 않았지만 향후 추가될 수 있습니다.

 

For SCHED_FIFO/SCHED_RR tasks:

p_rt->uclamp[UCLAMP_MIN] = 1024
p_rt->uclamp[UCLAMP_MAX] = 1024

이는 기본적으로 RT 작업의 기록 동작을 유지하는 시스템의 최대 성능 지점에서 실행되도록 향상됩니다.

RT 작업 기본값 uclamp_min 값은 sysctl을 통해 부팅 또는 런타임에 수정할 수 있습니다. 아래 섹션을 참조하십시오.

 

3.4.1 sched_util_clamp_min_rt_default

최대 성능 지점에서 RT 작업을 실행하는 것은 배터리로 구동되는 장치에서 비용이 많이 들기 때문에 필요하지 않습니다. 시스템 개발자가 최대 성능 지점까지 밀어붙이지 않고 이러한 작업에 대한 좋은 성능 보장을 제공할 수 있도록 이 sysctl 노브를 사용하면 항상 최대 성능 지점에서 실행되는 전원을 태우지 않고도 시스템 요구 사항을 해결할 수 있는 최고의 부스트 값을 조정할 수 있습니다.

애플리케이션 개발자는 성능 및 전원 인식을 보장하기 위해 작업별 사용 클램프 인터페이스를 사용하는 것이 권장됩니다. 이상적으로 이 노브는 시스템 설계자에 의해 0으로 설정되어야 하며 성능 요구 사항을 관리하는 작업은 앱에 맡겨야 합니다.

 

4. How to use util clamp

Util clamp는 사용자 공간 보조 전력 및 성능 관리의 개념을 촉진합니다. 스케줄러 수준에서는 최상의 결정을 내리는 데 필요한 정보가 없습니다. 그러나 Util clamp를 사용하면 사용자 공간이 스케줄러에게 작업 배치 및 주파수 선택에 대한 더 나은 결정을 내릴 수 있습니다.

최상의 결과는 애플리케이션이 실행 중인 시스템에 대해 어떠한 가정도 하지 않고 피드백 루프와 함께 사용하여 동적으로 모니터링하고 조정함으로써 얻어집니다. 궁극적으로 이는 더 나은 성능/와트에서 더 나은 사용자 경험을 가능하게 할 것입니다.

일부 시스템 및 사용 사례의 경우 정적 설정이 좋은 결과를 얻는데 도움이 될 것입니다. 이 경우 휴대성이 문제가 될 것입니다. 100, 200, 1024에서 어느 정도의 작업을 수행할 수 있는지는 시스템마다 다릅니다. 특정 목표 시스템이 없는 한 정적 설정은 피해야 합니다.

유틸리티 클램프나 이를 직접 활용하는 자체 포함 앱을 기반으로 전체 프레임워크를 만들 수 있는 가능성은 충분합니다.

 

4.1. Boost important and DVFS-latency-sensitive tasks

GUI 작업은 일어날 때 주파수를 높게 구동하는 것을 보장하기 위해 바쁘지 않을 수 있습니다. 그러나 원하는 사용자 경험을 제공하기 위해 특정 시간 내에 작업을 완료해야 합니다. 웨이크업 시 필요한 올바른 주파수는 시스템에 따라 달라집니다. 일부 저전력 시스템에서는 하이가 될 것이고, 다른 저전력 시스템에서는 로우 또는 0이 될 것입니다.

이 작업은 다음 웨이크업 시 더 높은 성능 지점에서 실행되도록 기한을 놓칠 때마다 UCLAMP_MIN 값을 증가시킬 수 있습니다. 특정 시스템에서 기한을 준수할 수 있는 가장 낮은 UCLAMP_MIN 값에 접근하여 해당 시스템에 대해 가능한 최상의 성능/와트를 달성해야 합니다.

이기종 시스템에서는 이 작업을 더 빠른 CPU에서 실행하는 것이 중요할 수 있습니다.

일반적으로 작업 배치 및 주파수 선택을 모두 의미하는 성능 수준 또는 지점으로 입력을 인식하는 것이 좋습니다.

 

4.2. Cap background tasks

서론에서 Android의 경우에 대해 설명한 것과 같습니다. 성능은 상관없지만 사용중이 되어 시스템의 불필요한 시스템 리소스를 소모할 수 있는 일부 백그라운드 작업의 경우 모든 앱이 UCLAMP_MAX를 낮출 수 있습니다.

 

4.3. Powersave mode

sched_util_clamp_max system wide interface를 사용하여 일반적으로 에너지 비효율적인 더 높은 성능의 지점에서 모든 작업이 작동하는 것을 제한할 수 있습니다.

이것은 cpufreq governor의 최대 주파수를 줄임으로써 동일한 것을 달성할 수 있기 때문에 uclamp에만 고유한 것이 아닙니다. 그것은 더 편리한 대체 인터페이스로 간주될 수 있습니다.

 

4.4. Per-app performance restriction

Middleware/Utility는 앱이 실행될 때마다 UCLAMP_MIN/MAX를 설정하여 최소한의 성능을 보장하거나 이러한 앱에 대한 성능 저하의 비용으로 시스템 전력 소모를 제한할 수 있는 옵션을 사용자에게 제공할 수 있습니다.

이동 중에도 커널을 컴파일하지 않고 성능을 희생하여 전력을 절약하고 싶지만 브라우저 성능을 그대로 유지하고 싶다면 uclamp를 사용하면 가능합니다.

 

5. Limitations

If task p0 is capped to run at 512:

p0->uclamp[UCLAMP_MAX] = 512

and it shares the rq with p1 which is free to run at any performance point:

p1->uclamp[UCLAMP_MAX] = 1024

then due to max aggregation the rq will be allowed to reach max performance point:

rq->uclamp[UCLAMP_MAX] = max(512, 1024) = 1024

 

p0과 p1이 모두 UCLAMP_MIN = 0이라고 가정하면 rq에 대한 주파수 선택은 작업의 실제 활용도 값에 따라 달라집니다.

 

p1이 작은 작업이지만 p0이 CPU 집약적인 작업인 경우 둘 다 동일한 rq에서 실행되고 있기 때문에 p1은 rq에서 주파수 캡핑을 유지하지만 p1은 모든 성능 지점에서 실행할 수 있는 p1은 실제로 해당 주파수에서 실행할 필요가 없습니다.

 

5.2. UCLAMP_MAX can break PELT (util_avg) signal

PELT는 CPU의 유휴 시간이 항상 존재하도록 신호가 증가함에 따라 주파수가 항상 증가할 것이라고 가정합니다. 그러나 UCLAMP_MAX를 사용하면 이러한 주파수 증가가 방지되어 일부 상황에서는 유휴 시간이 발생하지 않을 수 있습니다. 유휴 시간이 없으면 태스크가 비지 루프에 갇히게 되므로 util_avg가 1024가 됩니다.

아래에 설명된 문제와 결합하여 심각한 캡핑 작업이 캡핑되지 않은 작은 작업과 rq를 공유할 때 원치 않는 빈도 급증을 초래할 수 있습니다.

 

작업 p의 예로서 다음과 같은 작업이 있습니다:

p0->util_avg = 300
p0->uclamp[UCLAMP_MAX] = 0

idle CPU에서 깨어나면 이 CPU가 할 수 있는 최소 주파수(Fmin)로 실행됩니다. 여기에는 이 CPU에서 작업을 완료하는 가장 짧은 계산 시간을 지정하기 때문에 최대 CPU 주파수(Fmax)도 중요합니다.

rq->uclamp[UCLAMP_MAX] = 0

If the ratio of Fmax/Fmin is 3, then maximum value will be:

300 * (Fmax/Fmin) = 900

이는 900이 <1024>이기 때문에 CPU의 idle 시간이 계속 유지됨을 나타냅니다. 하지만 _actual_util_avg는 900이 아니라 300에서 900 사이일 것입니다. idle 시간이 있는 한 p-> util_avg 업데이트는 약간의 차이는 있지만 Fmax/Fmin에 비례하지는 않습니다.

 

p0->util_avg = 300 + small_error

이제 Fmax/Fmin의 비율이 4인 경우 최대값은 다음과 같습니다:

300 * (Fmax/Fmin) = 1200

 

이 값은 1024보다 크며 CPU에 idle 시간이 없음을 나타냅니다. 이렇게 되면 _actual_util_avg는 다음과 같이 됩니다:

p0->util_avg = 1024

이 CPU에서 작업 p1이 발생하면 다음과 같은 작업이 수행됩니다:

p1->util_avg = 200
p1->uclamp[UCLAMP_MAX] = 1024

그러면 CPU의 유효 UCLAMP_MAX는 max aggregation 규칙에 따라 1024가 됩니다. 그러나 캡핑된 p0 작업이 실행 중이고 심하게 조절되었기 때문에 rq->util_avg는 다음과 같습니다:

p0->util_avg = 1024
p1->util_avg = 200

rq->util_avg = 1024
rq->uclamp[UCLAMP_MAX] = 1024

따라서 p0가 조절되지 않았다면 다음과 같은 결과를 얻을 수 있기 때문에 주파수 스파이크가 발생합니다:

p0->util_avg = 300
p1->util_avg = 200

rq->util_avg = 500

Fmax가 아닌 CPU의 중간 성능 지점 근처에서 실행할 수 있습니다.

 

5.3. Schedutil response time issues

Schedutil에는 다음과 같은 세 가지 제한이 있습니다:

1. 하드웨어는 주파수 변경 요청에 응답하는 데 0이 아닌 시간이 소요됩니다. 일부 플랫폼에서는 몇 ms의 순서가 될 수 있습니다.

2. 고속 스위치가 아닌 시스템은 기상하고 주파수 변경을 수행하기 위해 작업자 마감 스레드가 필요하므로 측정 가능한 오버헤드가 추가됩니다.

3. schedutil rate_ limit_us는 이 rate_ limit_us 창에서 요청을 모두 삭제합니다.

 

상대적으로 작은 작업이 중요한 작업을 수행하고 있고, 작업을 시작할 때 특정 성능 지점이 필요한 경우 이러한 제한 사항으로 인해 원하는 시간에 원하는 작업을 수행할 수 없습니다.

이 한계는 uclamp를 사용할 때에만 영향을 미칠 뿐만 아니라 더 이상 점진적으로 상승하거나 하강하지 않으므로 더 널리 퍼질 것입니다. 우리는 깨우는 순서 작업과 각각의 uclamp 값에 따라 주파수 사이에서 쉽게 점프할 수 있습니다.

우리는 그것을 기본 시스템 자체의 기능의 한계로 간주합니다.

schedutil rate_limit_us의 동작을 개선할 수 있는 여지가 있지만 1 또는 2에 대해 할 일이 많지 않습니다. 이들은 시스템의 엄격한 한계로 간주됩니다.

 

참고문헌

https://docs.kernel.org/scheduler/sched-util-clamp.html