Sử dụng Simpleperf để đánh giá hiệu suất của một thiết bị. Simpleperf là một công cụ phân tích tài nguyên gốc cho cả ứng dụng và quy trình gốc trên Android. Sử dụng Trình phân tích CPU để kiểm tra mức sử dụng CPU của ứng dụng và hoạt động của luồng theo thời gian thực.
Có hai chỉ báo hiệu suất mà người dùng có thể nhìn thấy:
- Hiệu suất có thể dự đoán và dễ nhận biết. Giao diện người dùng (UI) có bị rớt khung hình hay hiển thị nhất quán ở tốc độ 60 khung hình/giây không? Âm thanh có phát mà không có tạp âm hoặc tiếng nổ không? Độ trễ giữa lúc người dùng chạm vào màn hình và hiệu ứng hiển thị trên màn hình là bao lâu?
- Thời lượng cần thiết cho các thao tác dài hơn (chẳng hạn như mở ứng dụng).
Lỗi đầu tiên dễ nhận thấy hơn lỗi thứ hai. Người dùng thường nhận thấy hiện tượng giật nhưng họ sẽ không thể phân biệt được thời gian khởi động ứng dụng là 500 ms hay 600 ms, trừ phi họ đang xem hai thiết bị cạnh nhau. Độ trễ cảm ứng có thể nhận thấy ngay lập tức và đóng góp đáng kể vào nhận thức về một thiết bị.
Do đó, trên một thiết bị nhanh, quy trình giao diện người dùng là điều quan trọng nhất trong hệ thống, ngoài những gì cần thiết để duy trì hoạt động của quy trình giao diện người dùng. Điều này có nghĩa là quy trình giao diện người dùng phải ưu tiên mọi công việc không cần thiết khác đối với giao diện người dùng linh hoạt. Để duy trì giao diện người dùng linh hoạt, bạn phải trì hoãn việc đồng bộ hoá ở chế độ nền, phân phối thông báo và các công việc tương tự nếu có thể chạy công việc trên giao diện người dùng. Bạn có thể chấp nhận đánh đổi hiệu suất của các thao tác dài hơn (thời gian chạy HDR+, khởi động ứng dụng, v.v.) để duy trì giao diện người dùng linh hoạt.
Dung lượng so với độ trễ
Khi xem xét hiệu suất của thiết bị, dung lượng và độ trễ là hai chỉ số có ý nghĩa.
Dung lượng
Dung lượng là tổng lượng tài nguyên mà thiết bị sở hữu trong một khoảng thời gian nhất định. Đây có thể là tài nguyên CPU, tài nguyên GPU, tài nguyên I/O, tài nguyên mạng, băng thông bộ nhớ hoặc bất kỳ chỉ số tương tự nào. Khi kiểm tra hiệu suất của toàn bộ hệ thống, bạn có thể tóm tắt các thành phần riêng lẻ và giả định một chỉ số duy nhất xác định hiệu suất (đặc biệt là khi điều chỉnh một thiết bị mới vì khối lượng công việc chạy trên thiết bị đó có thể được cố định).
Dung lượng của hệ thống thay đổi tuỳ theo tài nguyên điện toán trực tuyến. Thay đổi tần suất CPU/GPU là phương tiện chính để thay đổi dung lượng, nhưng cũng có các phương tiện khác như thay đổi số lượng lõi CPU trực tuyến. Do đó, dung lượng của hệ thống tương ứng với mức tiêu thụ điện năng; việc thay đổi dung lượng luôn dẫn đến sự thay đổi tương tự về mức tiêu thụ điện năng.
Dung lượng cần thiết tại một thời điểm nhất định chủ yếu do ứng dụng đang chạy xác định. Do đó, nền tảng có thể làm rất ít để điều chỉnh dung lượng cần thiết cho một khối lượng công việc nhất định và phương tiện để thực hiện việc này chỉ giới hạn ở các điểm cải tiến về thời gian chạy (khung Android, ART, Bionic, trình biên dịch/trình điều khiển GPU, hạt nhân).
Dao động
Mặc dù dung lượng cần thiết cho một khối lượng công việc rất dễ thấy, nhưng độ trễ là một khái niệm mơ hồ hơn. Để tìm hiểu về hiện tượng giật làm cản trở các hệ thống nhanh, bạn nên đọc bài viết có tiêu đề Trường hợp thiếu hiệu suất siêu máy tính: Đạt được hiệu suất tối ưu trên 8.192 bộ xử lý của ASCI Q. (Đây là một cuộc điều tra về lý do siêu máy tính ASCI Q không đạt được hiệu suất dự kiến và là một phần giới thiệu tuyệt vời về cách tối ưu hoá các hệ thống lớn.)
Trang này sử dụng thuật ngữ độ trễ để mô tả nội dung mà bài báo ASCI Q gọi là nhiễu. Độ trễ là hành vi ngẫu nhiên của hệ thống khiến công việc có thể nhận biết không chạy được. Đây thường là công việc phải chạy, nhưng có thể không có yêu cầu nghiêm ngặt về thời gian để chạy vào bất kỳ thời điểm cụ thể nào. Vì độ trễ là ngẫu nhiên, nên cực kỳ khó để chứng minh sự tồn tại của độ trễ cho một khối lượng công việc nhất định. Cũng rất khó để chứng minh rằng một nguồn giật đã biết là nguyên nhân gây ra một vấn đề cụ thể về hiệu suất. Các công cụ thường dùng nhất để chẩn đoán nguyên nhân gây ra hiện tượng giật (chẳng hạn như theo dõi hoặc ghi nhật ký) có thể gây ra hiện tượng giật riêng.
Các nguồn gây hiện tượng giật trong quá trình triển khai Android thực tế bao gồm:
- Độ trễ của trình lập lịch biểu
- Trình xử lý ngắt
- Mã trình điều khiển chạy quá lâu khi tính năng can thiệp trước hoặc gián đoạn bị tắt
- Softirq chạy trong thời gian dài
- Tranh chấp khoá (ứng dụng, khung, trình điều khiển hạt nhân, khoá liên kết, khoá mmap)
- Xung đột chỉ số mô tả tệp, trong đó luồng có mức độ ưu tiên thấp giữ khoá trên một tệp, ngăn luồng có mức độ ưu tiên cao chạy
- Chạy mã quan trọng đối với giao diện người dùng trong hàng đợi công việc có thể bị trì hoãn
- Chuyển đổi trạng thái rảnh của CPU
- Ghi nhật ký
- Độ trễ I/O
- Tạo quy trình không cần thiết (ví dụ: thông báo truyền tin
CONNECTIVITY_CHANGE
) - Bộ nhớ đệm trang bị hao tổn do không đủ bộ nhớ trống
Khoảng thời gian cần thiết cho một khoảng thời gian trễ nhất định có thể giảm hoặc không giảm khi dung lượng tăng lên. Ví dụ: nếu trình điều khiển tắt các hoạt động gián đoạn trong khi chờ đọc qua bus i2c, thì sẽ mất một khoảng thời gian cố định bất kể CPU ở tốc độ 384 MHz hay 2 GHz. Việc tăng dung lượng không phải là giải pháp khả thi để cải thiện hiệu suất khi có hiện tượng giật. Do đó, bộ xử lý nhanh hơn thường sẽ không cải thiện hiệu suất trong các tình huống bị hạn chế về độ trễ.
Cuối cùng, không giống như dung lượng, độ trễ gần như hoàn toàn nằm trong phạm vi của nhà cung cấp hệ thống.
Mức sử dụng bộ nhớ
Mức tiêu thụ bộ nhớ thường được cho là nguyên nhân gây ra hiệu suất kém. Mặc dù mức tiêu thụ không phải là vấn đề về hiệu suất, nhưng nó có thể gây ra hiện tượng giật thông qua chi phí của trình tiết kiệm bộ nhớ, việc khởi động lại dịch vụ và bộ nhớ đệm trang bị hao tổn. Việc giảm mức sử dụng bộ nhớ có thể tránh được các nguyên nhân trực tiếp gây ra hiệu suất kém, nhưng cũng có thể có các biện pháp cải tiến nhắm mục tiêu khác để tránh các nguyên nhân đó (ví dụ: ghim khung để ngăn khung đó bị phân trang khi sẽ được phân trang ngay sau đó).
Phân tích hiệu suất ban đầu của thiết bị
Bắt đầu từ một hệ thống có chức năng nhưng hoạt động kém và cố gắng khắc phục hành vi của hệ thống bằng cách xem xét từng trường hợp riêng lẻ về hiệu suất kém mà người dùng nhìn thấy không phải là một chiến lược hợp lý. Vì hiệu suất kém thường không dễ tái tạo (tức là hiện tượng giật) hoặc là vấn đề về ứng dụng, nên quá nhiều biến trong hệ thống đầy đủ sẽ khiến chiến lược này không hiệu quả. Do đó, rất dễ xác định sai nguyên nhân và cải thiện nhỏ trong khi bỏ lỡ các cơ hội mang tính hệ thống để khắc phục hiệu suất trên toàn hệ thống.
Thay vào đó, hãy sử dụng phương pháp chung sau đây khi hiển thị một thiết bị mới:
- Khởi động hệ thống vào giao diện người dùng với tất cả trình điều khiển đang chạy và một số chế độ cài đặt cơ bản của bộ điều tiết tần suất (nếu bạn thay đổi chế độ cài đặt bộ điều tiết tần suất, hãy lặp lại tất cả các bước bên dưới).
- Đảm bảo hạt nhân hỗ trợ điểm theo dõi
sched_blocked_reason
cũng như các điểm theo dõi khác trong quy trình hiển thị cho biết thời điểm khung hình được phân phối đến màn hình. - Theo dõi dài toàn bộ quy trình giao diện người dùng (từ khi nhận dữ liệu đầu vào qua IRQ đến khi quét cuối cùng) trong khi chạy một khối lượng công việc nhẹ và nhất quán (ví dụ: UiBench hoặc kiểm thử bóng trong TouchLatency).
- Khắc phục tình trạng sụt khung hình được phát hiện trong mức tải nhẹ và nhất quán.
- Lặp lại các bước 3-4 cho đến khi bạn có thể chạy mà không bị bỏ khung hình trong hơn 20 giây tại một thời điểm.
- Chuyển sang các nguồn giật khác mà người dùng có thể nhìn thấy.
Sau đây là một số việc đơn giản khác mà bạn có thể làm trong giai đoạn khởi động thiết bị:
- Đảm bảo hạt nhân của bạn có bản vá điểm theo dõi sched_blocked_reason. Điểm theo dõi này được bật bằng danh mục theo dõi lịch biểu trong systrace và cung cấp hàm chịu trách nhiệm ngủ khi luồng đó chuyển sang chế độ ngủ không thể gián đoạn. Điều này rất quan trọng đối với việc phân tích hiệu suất vì chế độ ngủ không gián đoạn là một chỉ báo rất phổ biến của hiện tượng giật.
- Đảm bảo bạn có đủ dữ liệu theo dõi cho GPU và quy trình hiển thị. Trên các SOC Qualcomm gần đây, các điểm theo dõi được bật bằng cách sử dụng:
adb shell "echo 1 > /d/tracing/events/kgsl/enable"
adb shell "echo 1 > /d/tracing/events/mdss/enable"
Các sự kiện này vẫn được bật khi bạn chạy systrace để bạn có thể xem thêm thông tin trong dấu vết về quy trình hiển thị (MDSS) trong phần mdss_fb0
. Trên SOC Qualcomm, bạn sẽ không thấy thêm thông tin nào về GPU trong chế độ xem systrace tiêu chuẩn, nhưng kết quả sẽ xuất hiện trong chính dấu vết (để biết thông tin chi tiết, hãy xem phần Tìm hiểu về systrace).
Bạn muốn có một sự kiện duy nhất từ loại hoạt động theo dõi màn hình này, sự kiện này trực tiếp cho biết một khung hình đã được phân phối đến màn hình. Từ đó, bạn có thể xác định xem mình đã đạt được thời gian khung hình thành công hay chưa; nếu sự kiện Xn xảy ra trong vòng chưa đến 16,7 ms sau sự kiện Xn-1 (giả sử màn hình 60 Hz), thì bạn biết rằng mình không bị giật. Nếu SOC của bạn không cung cấp các tín hiệu như vậy, hãy làm việc với nhà cung cấp để lấy các tín hiệu đó. Rất khó để gỡ lỗi hiện tượng giật nếu không có tín hiệu rõ ràng về việc hoàn tất khung hình.
Sử dụng điểm chuẩn tổng hợp
Điểm chuẩn tổng hợp rất hữu ích để đảm bảo chức năng cơ bản của thiết bị có hoạt động hay không. Tuy nhiên, việc coi điểm chuẩn là chỉ số đại diện cho hiệu suất thiết bị nhận thấy là không hữu ích.
Dựa trên kinh nghiệm với các SOC, sự khác biệt về hiệu suất điểm chuẩn tổng hợp giữa các SOC không tương quan với sự khác biệt tương tự về hiệu suất giao diện người dùng có thể nhận thấy (số khung hình bị bỏ qua, thời gian khung hình thứ 99, v.v.). Điểm chuẩn tổng hợp là điểm chuẩn chỉ về dung lượng; độ trễ chỉ ảnh hưởng đến hiệu suất đo lường của các điểm chuẩn này bằng cách lấy thời gian từ hoạt động hàng loạt của điểm chuẩn. Do đó, điểm chuẩn tổng hợp hầu như không liên quan đến chỉ số hiệu suất mà người dùng cảm nhận được.
Hãy xem xét hai SOC chạy Điểm chuẩn X kết xuất 1000 khung giao diện người dùng và báo cáo tổng thời gian kết xuất (điểm số càng thấp càng tốt).
- SOC 1 kết xuất mỗi khung của Điểm chuẩn X trong 10 ms và đạt điểm số 10.000.
- SOC 2 kết xuất 99% số khung hình trong 1 mili giây nhưng 1% số khung hình trong 100 mili giây và đạt điểm số 19.900, cao hơn đáng kể.
Nếu điểm chuẩn cho biết hiệu suất thực tế của giao diện người dùng, thì bạn sẽ không thể sử dụng SOC 2. Giả sử tốc độ làm mới là 60 Hz, SOC 2 sẽ có một khung hình giật mỗi khi hoạt động trong 1,5 giây. Trong khi đó, SOC 1 (SOC chậm hơn theo Điểm chuẩn X) sẽ hoạt động hoàn hảo.
Sử dụng báo cáo lỗi
Báo cáo lỗi đôi khi hữu ích cho việc phân tích hiệu suất, nhưng vì báo cáo lỗi có dung lượng lớn nên hiếm khi hữu ích cho việc gỡ lỗi các vấn đề giật ngẫu nhiên. Các chỉ số này có thể cung cấp một số gợi ý về những gì hệ thống đang làm tại một thời điểm nhất định, đặc biệt là nếu hiện tượng giật xảy ra trong quá trình chuyển đổi ứng dụng (được ghi lại trong báo cáo lỗi). Báo cáo lỗi cũng có thể cho biết thời điểm hệ thống gặp sự cố nghiêm trọng hơn có thể làm giảm dung lượng hiệu quả của hệ thống (chẳng hạn như điều tiết nhiệt hoặc phân mảnh bộ nhớ).
Sử dụng TouchLatency
Một số ví dụ về hành vi xấu đến từ TouchLatency, đây là mức tải định kỳ ưu tiên dùng cho Pixel và Pixel XL. Tính năng này có sẵn tại frameworks/base/tests/TouchLatency
và có hai chế độ: độ trễ cảm ứng và quả bóng nảy (để chuyển đổi chế độ, hãy nhấp vào nút ở góc trên bên phải).
Kiểm thử quả bóng nảy đơn giản như chính tên gọi của nó: Một quả bóng nảy xung quanh màn hình mãi mãi, bất kể người dùng nhập gì. Đây cũng thường là thử nghiệm khó nhất để chạy hoàn hảo, nhưng càng gần đến việc chạy mà không bị bỏ khung hình, thiết bị của bạn càng tốt. Kiểm thử quả bóng nảy là một thử nghiệm khó vì đây là một khối lượng công việc nhỏ nhưng nhất quán hoàn hảo chạy ở xung nhịp rất thấp (giả sử thiết bị có trình quản lý tần số; nếu thiết bị đang chạy với xung nhịp cố định, hãy giảm xung nhịp CPU/GPU xuống gần mức tối thiểu khi chạy kiểm thử quả bóng nảy lần đầu tiên). Khi hệ thống chuyển sang trạng thái rảnh và xung nhịp giảm gần hơn đến trạng thái rảnh, thời gian CPU/GPU cần thiết cho mỗi khung hình sẽ tăng lên. Bạn có thể xem quả bóng và thấy các vật thể bị giật, đồng thời bạn cũng có thể thấy các khung hình bị thiếu trong systrace.
Vì khối lượng công việc rất nhất quán, bạn có thể xác định hầu hết các nguồn giật dễ dàng hơn nhiều so với hầu hết các khối lượng công việc mà người dùng nhìn thấy bằng cách theo dõi chính xác những gì đang chạy trên hệ thống trong mỗi khung hình bị thiếu thay vì quy trình giao diện người dùng. Tốc độ xung nhịp thấp hơn làm tăng hiệu ứng của hiện tượng giật bằng cách làm tăng khả năng hiện tượng giật sẽ gây ra hiện tượng bỏ khung hình. Do đó, TouchLatency càng gần 60FPS thì càng ít có khả năng bạn gặp phải các hành vi hệ thống xấu gây ra hiện tượng giật không thường xuyên và khó tái tạo trong các ứng dụng lớn hơn.
Vì độ trễ thường (nhưng không phải lúc nào cũng) không đổi theo tốc độ xung nhịp, hãy sử dụng một chương trình kiểm thử chạy ở tốc độ xung nhịp rất thấp để chẩn đoán độ trễ vì những lý do sau:
- Không phải tất cả độ trễ đều không đổi theo tốc độ xung nhịp; nhiều nguồn chỉ tiêu tốn thời gian của CPU.
- Trình điều phối nên đặt thời gian khung hình trung bình gần với thời hạn bằng cách giảm tốc độ xung nhịp, vì vậy, thời gian chạy công việc không phải giao diện người dùng có thể đẩy thời gian này vượt quá giới hạn để làm giảm khung hình.