Ngày phát hành:
Android 11 (API cấp 30) – API Nhiệt
Android 12 (API cấp 31) – API NDK
(Xem trước) Android 15 (DP1) – getThermalHeadroomThresholds()
Hiệu suất tiềm năng của ứng dụng bị giới hạn bởi trạng thái nhiệt của thiết bị. Trạng thái nhiệt có thể thay đổi tuỳ theo các yếu tố đặc thù như thời tiết, mức sử dụng gần đây và thiết kế tản nhiệt của thiết bị. Thiết bị chỉ có thể duy trì mức hiệu suất trong một khoảng thời gian giới hạn trước khi bị điều tiết nhiệt. Mục tiêu chính của việc triển khai là đạt được mục tiêu về hiệu suất mà không bị vượt quá giới hạn nhiệt. Thermal API (API Nhiệt) giúp việc này trở nên khả thi mà không cần đến để tối ưu hoá theo thiết bị. Hơn nữa, khi gỡ lỗi hiệu suất khi biết liệu trạng thái nhiệt của thiết bị có làm hạn chế hiệu suất hay không là rất quan trọng.
Các công cụ phát triển trò chơi thường có các thông số hiệu suất trong thời gian chạy giúp điều chỉnh mức tải mà công cụ phân cho thiết bị. Ví dụ: các thông số này có thể thiết lập số lượng luồng công việc, chỉ định luồng công việc cho các nhân xử lý lớn và nhỏ, các tuỳ chọn về độ trung thực của GPU cũng như độ phân giải bộ đệm khung. Trong Unity Engine, trò chơi nhà phát triển có thể điều chỉnh khối lượng công việc bằng cách thay đổi chất lượng Chế độ cài đặt bằng cách dùng trình bổ trợ Hiệu suất thích ứng. Đối với Unreal Engine, hãy dùng phần Cài đặt khả năng mở rộng để điều chỉnh một cách linh động về mức chất lượng.
Khi thiết bị đạt đến trạng thái nhiệt không an toàn, trò chơi có thể tránh bị điều tiết bằng cách giảm mức tải thông qua các thông số này. Để tránh việc bị điều tiết, bạn nên theo dõi trạng thái nhiệt của thiết bị và chủ động điều chỉnh mức tải của công cụ phát triển trò chơi. Khi thiết bị quá nóng, mức tải phải giảm xuống dưới mức hiệu suất ổn định để phân tán nhiệt. Sau khoảng nhiệt giảm xuống mức an toàn hơn, trò chơi có thể tăng chế độ cài đặt chất lượng một lần nữa, nhưng hãy nhớ tìm một mức chất lượng bền vững để có thời gian chơi tối ưu.
Bạn có thể theo dõi trạng thái nhiệt của thiết bị bằng cách thăm dò phương thức getThermalHeadroom
. Phương thức này dự đoán khoảng thời gian thiết bị có thể duy trì dòng điện
mà không bị quá nóng. Nếu khoảng thời gian này ít hơn thời gian cần thiết để chạy mức tải, thì trò chơi sẽ giảm mức tải xuống một mức ổn định. Ví dụ: trò chơi có thể chuyển sang các nhân xử lý nhỏ hơn, giảm tốc độ khung hình hoặc giảm độ trung thực.
Thu nhận trình quản lý nhiệt
Để sử dụng API Nhiệt, trước tiên, bạn cần có Trình quản lý nhiệt
C++
AThermalManager* thermal_manager = AThermal_acquireManager();
Java
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
Dự đoán khoảng nhiệt khoảng x giây trước để kiểm soát tốt hơn
Bạn có thể yêu cầu hệ thống dự đoán nhiệt độ trước x giây bằng khối lượng công việc hiện tại. Tính năng này giúp bạn kiểm soát chi tiết hơn và có thêm thời gian để ứng phó bằng cách giảm khối lượng công việc để ngăn tình trạng điều tiết nhiệt kích hoạt.
Kết quả dao động từ 0.0f (không điều tiết, THERMAL_STATUS_NONE
) đến 1.0f
(điều tiết mạnh, THERMAL_STATUS_SEVERE
).
Nếu có nhiều mức chất lượng đồ hoạ trong trò chơi của mình, bạn có thể làm theo
Nguyên tắc về khoảng nhiệt.
C++
float thermal_headroom = AThermal_getThermalHeadroom(10);
ALOGI("ThermalHeadroom in 10 sec: %f", thermal_headroom);
Java
float thermalHeadroom = powerManager.getThermalHeadroom(10);
Log.d("ADPF", "ThermalHeadroom in 10 sec: " + thermalHeadroom);
Ngoài ra, dựa vào trạng thái nhiệt để làm rõ
Mỗi mẫu thiết bị có thể được thiết kế theo cách khác nhau. Một số thiết bị có thể phân phối nhiệt tốt hơn và do đó có thể chịu được khoảng nhiệt cao hơn trước khi bị điều tiết. Nếu bạn muốn đọc một nhóm các phạm vi được đơn giản hoá khoảng nhiệt, bạn có thể kiểm tra trạng thái nhiệt để nắm được khoảng nhiệt trên thiết bị hiện tại.
C++
AThermalStatus thermal_status = AThermal_getCurrentThermalStatus(thermal_manager);
ALOGI("ThermalStatus is: %d", thermal_status);
Java
int thermalStatus = powerManager.getCurrentThermalStatus();
Log.d("ADPF", "ThermalStatus is: " + thermalStatus);
Nhận thông báo khi trạng thái nhiệt thay đổi
Bạn cũng có thể tránh thăm dò thermalHeadroom
cho đến khi thermalStatus
đạt đến
một cấp độ nhất định (ví dụ: THERMAL_STATUS_LIGHT
).
Để thực hiện việc này, bạn có thể đăng ký một lệnh gọi lại để hệ thống có thể thông báo cho bạn mỗi khi
trạng thái đã thay đổi.
C++
int result = AThermal_registerThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether you have previously registered callback that
// hasn’t been unregistered
}
Java
// 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);
Nhớ xoá trình nghe khi hoàn tất
C++
int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether the callback has been registered previously
}
Java
powerManager.removeThermalStatusListener(listener);
Dọn dẹp
Sau khi hoàn tất, bạn cần dọn dẹp thermal_manager mà bạn đã mua. Nếu bạn đang sử dụng Java, tham chiếu PowerManager có thể tự động là rác đã thu thập cho bạn. Nhưng nếu bạn đang sử dụng API Java thông qua JNI và có đã giữ lại tham chiếu, hãy nhớ dọn dẹp tham chiếu!
C++
AThermal_releaseManager(thermal_manager);
Để xem hướng dẫn đầy đủ về cách triển khai Thermal API (API Nhiệt) trên trò chơi C++ gốc bằng cả API C++ (API NDK) và API Java (thông qua JNI), hãy xem tài liệu Tích hợp Phần Thermal API (API Nhiệt) trong Lớp học lập trình về khả năng thích ứng .
Nguyên tắc về khoảng nhiệt
Bạn có thể theo dõi trạng thái nhiệt của thiết bị bằng cách thăm dò phương thức getThermalHeadroom
. Phương thức này dự đoán khoảng thời gian thiết bị có thể duy trì dòng điện
hiệu suất trước khi đạt THERMAL_STATUS_SEVERE
.
Ví dụ: nếu getThermalHeadroom(30)
trả về 0, 8, thì tức là trong 30
giây, khoảng trần dự kiến sẽ đạt 0,8, trong khi khoảng cách là 0,2
do điều tiết nghiêm trọng, hoặc 1.0. Nếu thời gian ít hơn lượng cần thiết để
thì trò chơi của bạn sẽ giảm khối lượng công việc xuống
cấp độ. Ví dụ: trò chơi có thể giảm tốc độ khung hình, độ chân thực thấp hơn hoặc
giảm khả năng kết nối mạng.
Trạng thái và ý nghĩa của trạng thái nhiệt
- Nếu thiết bị hiện không điều tiết nhiệt:
- Một số yếu tố điều tiết, nhưng không ảnh hưởng đáng kể đến hiệu suất:
- Điều tiết đáng kể ảnh hưởng đến hiệu suất:
Các hạn chế của thiết bị Thermal API (API Nhiệt)
Có một số hạn chế đã biết hoặc yêu cầu bổ sung của API Nhiệt, do cho đến việc triển khai API Nhiệt trên các thiết bị cũ. Các giới hạn và cách thức để giải quyết chúng như sau:
- Đừng gọi API
GetThermalHeadroom()
quá thường xuyên. Làm như vậy sẽ kết quả là API trả về NaN. Bạn nên gọi tối đa một lần mỗi giây. - Nếu giá trị ban đầu của
GetThermalHeadroom()
là NaN thì API sẽ không có trên thiết bị - Nếu
GetThermalHeadroom()
trả về một giá trị cao (ví dụ: 0,85 trở lên) vàGetCurrentThermalStatus()
vẫn trả vềTHERMAL_STATUS_NONE
, trạng thái là có thể chưa được cập nhật. Sử dụng phương pháp phỏng đoán để ước tính chính xác chế độ điều tiết nhiệt hoặc chỉ sử dụnggetThermalHeadroom()
mà khônggetCurrentThermalStatus()
.
Ví dụ về Heuristics:
- Kiểm tra để đảm bảo rằng API Nhiệt được hỗ trợ.
isAPISupported()
kiểm tra giá trị của lệnh gọi đầu tiên đếngetThermalHeadroom
để đảm bảo giá trị này không phải là 0 hoặc NaN và bỏ qua việc sử dụng API nếu giá trị đầu tiên là 0 hoặc NaN. - Nếu
getCurrentThermalStatus()
trả về một giá trị không phải làTHERMAL_STATUS_NONE
, thiết bị đang bị điều tiết nhiệt. - Nếu
getCurrentThermalStatus()
tiếp tục trả vềTHERMAL_STATUS_NONE
, thì giá trị này không nhất thiết có nghĩa là thiết bị hiện không bị điều tiết nhiệt. Có thể có nghĩa làgetCurrentThermalStatus()
không được hỗ trợ trên thiết bị. Kiểm tra giá trị trả về củagetThermalHeadroom()
để đảm bảo điều kiện của thiết bị. - Nếu
getThermalHeadroom()
trả về giá trị > 1.0, trạng thái có thể thực sự từTHERMAL_STATUS_SEVERE
trở lên, hãy giảm khối lượng công việc ngay lập tức và duy trì khối lượng công việc thấp hơn cho đến khigetThermalHeadroom()
trả về giá trị thấp hơn - Nếu
getThermalHeadroom()
trả về giá trị 0,95, trạng thái có thể thực sự làTHERMAL_STATUS_MODERATE
trở lên, hãy giảm khối lượng công việc ngay lập tức và chú ý để tránh chỉ số đọc cao hơn - Nếu
getThermalHeadroom()
trả về giá trị 0,85, trạng thái có thể thực sự làTHERMAL_STATUS_LIGHT
, hãy chú ý theo dõi và giảm khối lượng công việc nếu có thể
Mã giả:
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.
}
}
}
Sơ đồ: