출시일:
Android 11 (API 수준 30) - Thermal API
Android 12 (API 수준 31) - NDK API
(미리보기) Android 15 (DP1) - getThermalHeadroomThresholds()
앱은 기기의 열 상태에 따라 잠재적으로 성능이 제한되며, 기기의 열 상태는 날씨, 최근 사용량, 기기의 열 관련 설계와 같은 특성에 따라 달라질 수 있습니다. 장치는 느슨하게 끊어질 수 있습니다. 구현의 주요 목표는 열 제한을 초과하지 않고 성능 목표를 달성하는 것입니다. Thermal API를 사용하면 별도의 작업 없이 기기별로 최적화할 수 있습니다. 또한 성능을 디버깅할 때 기기의 열 상태가 성능을 제한하는지 확인하는 것이 매우 중요합니다. 또한 성능 문제를 디버깅할 때 기기의 열 상태가 성능을 제한하는지 확인하는 것이 매우 중요합니다.
게임 엔진에는 일반적으로 엔진이 기기에 부여하는 워크로드를 조정할 수 있는 런타임 성능 매개변수가 있습니다. 예를 들어, 이러한 매개변수는 작업자 스레드 수, 큰 코어와 작은 코어의 작업자 스레드 어피니티, GPU 충실도 옵션, 프레임 버퍼 해상도를 설정할 수 있습니다. Unity Engine에서 개발자는 품질 보증을 변경하여 워크로드를 조정할 수 있습니다. 설정 Adaptive Performance 플러그인을 사용합니다. Unreal Engine의 경우 확장성 설정을 사용하여 동적으로 조정할 수 있습니다.
기기가 안전하지 않은 열 상태에 도달하면 게임은 이러한 매개변수를 통해 워크로드를 줄여 성능이 제한되는 상황을 피할 수 있습니다. 제한 상황을 피하려면 기기의 열 상태를 모니터링하고 게임 엔진 워크로드를 미리 조정해야 합니다. 기기가 일단 과열되면 열을 방출하기 위해 워크로드가 지속 가능한 성능 수준 아래로 떨어져야 합니다. 후(After) 열 헤드룸이 더 안전한 수준으로 줄어들면 게임에서 지속 가능한 품질 수준을 찾아야 합니다. 최적의 재생 시간을 제공합니다.
getThermalHeadroom
메서드를 폴링하여 기기의 열 상태를 모니터링할 수 있습니다. 이 메서드는 기기가 전류 전압을 유지할 수 있는
성능을 향상시키는 데 도움이 됩니다. 시간이 워크로드를 실행하는 데 필요한 시간보다 적으면 게임에서 지속 가능한 수준으로 워크로드를 줄여야 합니다. 예를 들어 게임은 더 작은 코어로 전환하거나 프레임 속도를 낮추거나 충실도를 낮출 수 있습니다.
![ADPF Thermal API 사전 통합](https://developer.android.com/static/games/optimize/adpf/images/adpf_thermal_pre-integration.png?authuser=9&hl=ko)
![ADPF Thermal API 사후 통합](https://developer.android.com/static/games/optimize/adpf/images/adpf_thermal_post-integration.png?authuser=9&hl=ko)
Thermal Manager 획득
Thermal API를 사용하려면 먼저 Thermal Manager를 획득해야 합니다.
C++
AThermalManager* thermal_manager = AThermal_acquireManager();
자바
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
더욱 세밀한 제어를 위해 열 헤드룸을 x초 미리 예측
CANNOT TRANSLATE 현재 워크로드에 적합합니다 이렇게 하면 더 세밀하게 제어할 수 있으며, 워크로드를 줄여 열 조절이 시작되는 것을 방지합니다.
결과 범위는 0.0f (제한 없음, THERMAL_STATUS_NONE
)~1.0f입니다.
(과도한 제한, THERMAL_STATUS_SEVERE
)
게임의 그래픽 품질 수준이 다른 경우
열 헤드룸 가이드라인.
C++
float thermal_headroom = AThermal_getThermalHeadroom(10);
ALOGI("ThermalHeadroom in 10 sec: %f", thermal_headroom);
자바
float thermalHeadroom = powerManager.getThermalHeadroom(10);
Log.d("ADPF", "ThermalHeadroom in 10 sec: " + thermalHeadroom);
또는 열 상태를 확인하여 명확하게 확인합니다.
기기 모델마다 설계 방식이 다를 수 있습니다. 일부 기기에서는 열을 더 잘 분배하여 더 높은 열 헤드룸을 견딜 수 있습니다. 될 수 있습니다 원하는 기간에 대한 간단한 그룹 범위를 열 상태를 확인하여 열 헤드룸 값을 반환합니다.
C++
AThermalStatus thermal_status = AThermal_getCurrentThermalStatus(thermal_manager);
ALOGI("ThermalStatus is: %d", thermal_status);
자바
int thermalStatus = powerManager.getCurrentThermalStatus();
Log.d("ADPF", "ThermalStatus is: " + thermalStatus);
열 상태가 변경되면 알림 받기
또한 thermalStatus
에 도달할 때까지 thermalHeadroom
폴링을 피할 수 있습니다.
특정 수준 (예: THERMAL_STATUS_LIGHT
)
그러기 위해서는 콜백을 등록하여
상태가 변경되었습니다.
C++
int result = AThermal_registerThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether you have previously registered callback that
// hasn’t been unregistered
}
자바
// PowerManager.OnThermalStatusChangedListener is an interface, thus you can
// also define a class that implements the methods
PowerManager.OnThermalStatusChangedListener listener = new
PowerManager.OnThermalStatusChangedListener() {
@Override
public void onThermalStatusChanged(int status) {
Log.d("ADPF", "ThermalStatus changed: " + status);
// check the status and flip the flag to start/stop pooling when
// applicable
}
};
powerManager.addThermalStatusListener(listener);
완료되면 리스너를 삭제해야 합니다.
C++
int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether the callback has been registered previously
}
자바
powerManager.removeThermalStatusListener(listener);
정리
완료한 후에는 획득한 thermal_manager를 삭제해야 합니다. Java를 사용하는 경우 PowerManager 참조가 자동으로 가비지로 분류될 수 있습니다. 자동으로 수집됩니다 그러나 JNI를 통해 Java API를 사용하고 있고 참조가 보관되었다면 참조를 정리하는 것을 잊지 마세요.
C++
AThermal_releaseManager(thermal_manager);
다음을 사용하여 네이티브 C++ 게임에서 Thermal API를 구현하는 방법에 관한 전체 가이드 C++ API (NDK API)와 Java API (JNI를 통해)에 대한 자세한 내용은 통합 적응성 Codelab의 Thermal API 섹션 섹션으로 이동합니다.
열 헤드룸 가이드라인
getThermalHeadroom
메서드를 폴링하여 기기의 열 상태를 모니터링할 수 있습니다. 이 메서드는 기기가 전류 전압을 유지할 수 있는
THERMAL_STATUS_SEVERE
에 도달할 때까지의 실적이 떨어집니다.
예를 들어 getThermalHeadroom(30)
이 0.8을 반환하면 30에서 8이라는 의미입니다.
헤드룸은 0.8에 도달할 것으로 예상되며 여기서 거리가 0.2입니다.
또는 1.0입니다 시간이 충분하지 않은 경우
게임에서 워크로드를 지속 가능한
있습니다. 예를 들어 게임에서 프레임 속도를 줄이거나, 해상도를 낮추거나,
네트워크 연결 작업을 줄여줍니다
열 상태 및 의미
- 기기가 온도로 제한되고 있지 않은 경우:
<ph type="x-smartling-placeholder">
- </ph>
THERMAL_STATUS_NONE
- 일부 제한이 있지만 성능에 큰 영향을 미치지 않음: <ph type="x-smartling-placeholder">
- 성능에 영향을 미치는 심각한 제한: <ph type="x-smartling-placeholder">
Thermal API의 기기 제한사항
Thermal API에는 몇 가지 알려진 제한사항이나 추가 요구사항이 있습니다. Thermal API 구현에 이르기까지 한계 및 방법 방법은 다음과 같습니다.
GetThermalHeadroom()
API를 너무 자주 호출하지 마세요. 이렇게 하면 API가 NaN을 반환합니다. 초당 최대 한 번 호출해야 합니다.GetThermalHeadroom()
의 초깃값이 NaN이면 API는 기기에서 사용 가능GetThermalHeadroom()
가 높은 값 (예: 0.85 이상)을 반환하고GetCurrentThermalStatus()
는 여전히THERMAL_STATUS_NONE
를 반환합니다. 상태는 다음과 같습니다. 업데이트되지 않았을 가능성이 높습니다. 휴리스틱을 사용하여 올바른 열 제한 예측 상태를 알리거나getCurrentThermalStatus()
없이getThermalHeadroom()
를 사용하면 됩니다.
휴리스틱의 예:
- Thermal API가 지원되는지 확인합니다.
isAPISupported()
는 다음 값을 확인합니다. 첫 번째getThermalHeadroom
호출을 통해 0 또는 NaN이 아니어야 합니다. 첫 번째 값이 0 또는 NaN이면 API를 사용하여 건너뜁니다. getCurrentThermalStatus()
가THERMAL_STATUS_NONE
: 기기가 열로 제한되고 있습니다.getCurrentThermalStatus()
가THERMAL_STATUS_NONE
를 계속 반환하면 기기가 온도로 인해 제한되고 있지 않음을 의미하지는 않습니다. 가능getCurrentThermalStatus()
가 기기에서 지원되지 않음을 의미합니다.getThermalHeadroom()
의 반환 값을 확인하여 있습니다.getThermalHeadroom()
가 > 값을 반환하는 경우 1.0인 경우 상태는 실제로THERMAL_STATUS_SEVERE
이상이면 워크로드를 즉시 줄이고getThermalHeadroom()
가 더 낮은 값을 반환할 때까지 더 낮은 워크로드 유지getThermalHeadroom()
가 0.95 값을 반환하면 상태는 다음과 같을 수 있습니다. 실제로THERMAL_STATUS_MODERATE
이상이면 워크로드를 즉시 줄이세요. 높은 판독값을 피하도록getThermalHeadroom()
가 0.85 값을 반환하면 상태는 다음과 같을 수 있습니다.THERMAL_STATUS_LIGHT
상태이므로 경계하고 워크로드는 줄일 수 있습니다. 가능하다면
의사코드:
bool isAPISupported() {
float first_value_of_thermal_headroom = getThermalHeadroom();
if ( first_value_of_thermal_headroom == 0 ||
first_value_of_thermal_headroom == NaN ) {
// Checked the thermal Headroom API's initial return value
// it is NaN or 0,so, return false (not supported)
return false;
}
return true;
}
if (!isAPISupported()) {
// Checked the thermal Headroom API's initial return value, it is NaN or 0
// Don’t use the API
} else {
// Use thermalStatus API to check if it returns valid values.
if (getCurrentThermalStatus() > THERMAL_STATUS_NONE) {
// The device IS being thermally throttled
} else {
// The device is not being thermally throttled currently. However, it
// could also be an indicator that the ThermalStatus API may not be
// supported in the device.
// Currently this API uses predefined threshold values for thermal status
// mapping. In the future you may be able to query this directly.
float thermal_headroom = getThermalHeadroom();
if ( thermal_headroom > 1.0) {
// The device COULD be severely throttled.
} else if ( thermal_headroom > 0.95) {
// The device COULD be moderately throttled.
} else if ( thermal_headroom > 0.85) {
// The device COULD be experiencing light throttling.
}
}
}
다이어그램:
<ph type="x-smartling-placeholder">