Hệ thống xây dựng Android cho Android 13 trở xuống hỗ trợ sử dụng tính năng tối ưu hoá theo hướng dẫn của hồ sơ (PGO) của Clang trên các mô-đun Android gốc có quy tắc bản dựng blueprint. Trang này mô tả Clang PGO, cách liên tục tạo và cập nhật hồ sơ dùng cho PGO, cũng như cách tích hợp PGO với hệ thống xây dựng (có trường hợp sử dụng).
Lưu ý: Tài liệu này mô tả cách sử dụng PGO trong nền tảng Android. Để tìm hiểu cách sử dụng PGO từ một ứng dụng Android, hãy truy cập vào trang này.
Giới thiệu về Clang PGO
Clang có thể thực hiện tính năng tối ưu hoá theo hướng dẫn của hồ sơ bằng hai loại hồ sơ:
- Hồ sơ dựa trên khả năng đo lường được tạo từ một chương trình mục tiêu được đo lường. Các hồ sơ này rất chi tiết và gây ra mức hao tổn thời gian chạy cao.
- Hồ sơ dựa trên hoạt động lấy mẫu thường do các bộ đếm phần cứng lấy mẫu tạo ra. Các chỉ số này gây ra mức hao tổn thời gian chạy thấp và có thể được thu thập mà không cần đo lường hoặc sửa đổi tệp nhị phân. Các hồ sơ này ít chi tiết hơn so với hồ sơ dựa trên khả năng đo lường.
Tất cả hồ sơ phải được tạo từ một mức tải đại diện thực hiện hành vi thông thường của ứng dụng. Mặc dù Clang hỗ trợ cả dựa trên AST (-fprofile-instr-generate
) và dựa trên LLVM IR (-fprofile-generate)
, nhưng Android chỉ hỗ trợ dựa trên LLVM IR cho PGO dựa trên đo lường.
Bạn cần có các cờ sau để tạo bản dựng cho tính năng thu thập hồ sơ:
-fprofile-generate
cho thiết bị đo lường dựa trên hồng ngoại. Với tuỳ chọn này, phần phụ trợ sử dụng phương pháp cây lấp kín tối thiểu có trọng số để giảm số lượng điểm đo lường và tối ưu hoá vị trí của các điểm đo lường đó cho các cạnh có trọng số thấp (cũng sử dụng tuỳ chọn này cho bước liên kết). Trình điều khiển Clang tự động truyền thời gian chạy phân tích tài nguyên (libclang_rt.profile-arch-android.a
) đến trình liên kết. Thư viện này chứa các quy trình để ghi hồ sơ vào ổ đĩa khi thoát chương trình.-gline-tables-only
để thu thập hồ sơ dựa trên hoạt động lấy mẫu nhằm tạo ra thông tin gỡ lỗi tối thiểu.
Bạn có thể sử dụng hồ sơ cho PGO bằng cách sử dụng -fprofile-use=pathname
hoặc -fprofile-sample-use=pathname
cho hồ sơ dựa trên đo lường và hồ sơ dựa trên lấy mẫu tương ứng.
Lưu ý: Khi bạn thực hiện các thay đổi đối với mã, nếu Clang không thể sử dụng dữ liệu hồ sơ nữa, thì mã này sẽ tạo ra cảnh báo -Wprofile-instr-out-of-date
.
Sử dụng PGO
Quá trình sử dụng PGO bao gồm các bước sau:
- Tạo thư viện/tệp thực thi có khả năng đo lường bằng cách truyền
-fprofile-generate
cho trình biên dịch và trình liên kết. - Thu thập hồ sơ bằng cách chạy một khối lượng công việc tiêu biểu trên tệp nhị phân được đo lường.
- Hậu xử lý hồ sơ bằng tiện ích
llvm-profdata
(để biết thông tin chi tiết, hãy xem phần Xử lý tệp hồ sơ LLVM). - Sử dụng các cấu hình để áp dụng PGO bằng cách truyền
-fprofile-use=<>.profdata
cho trình biên dịch và trình liên kết.
Đối với PGO trong Android, bạn nên thu thập hồ sơ ngoại tuyến và kiểm tra cùng với mã để đảm bảo các bản dựng có thể tái tạo. Bạn có thể sử dụng cấu hình khi mã phát triển, nhưng phải tạo lại định kỳ (hoặc bất cứ khi nào Clang cảnh báo rằng cấu hình đã lỗi thời).
Thu thập hồ sơ
Clang có thể sử dụng các hồ sơ được thu thập bằng cách chạy phép đo điểm chuẩn bằng một bản dựng được đo lường của thư viện hoặc bằng cách lấy mẫu bộ đếm phần cứng khi chạy phép đo điểm chuẩn. Hiện tại, Android không hỗ trợ việc sử dụng tính năng thu thập hồ sơ dựa trên hoạt động lấy mẫu, vì vậy, bạn phải thu thập hồ sơ bằng một bản dựng được đo lường:
- Xác định một điểm chuẩn và tập hợp các thư viện do điểm chuẩn đó thực thi chung.
- Thêm các thuộc tính
pgo
vào điểm chuẩn và thư viện (thông tin chi tiết bên dưới). - Tạo một bản dựng Android có bản sao được đo lường của các thư viện này bằng cách sử dụng:
make ANDROID_PGO_INSTRUMENT=benchmark
benchmark
là phần giữ chỗ xác định bộ sưu tập thư viện được đo lường trong quá trình xây dựng. Dữ liệu đầu vào đại diện thực tế (và có thể là một tệp thực thi khác liên kết với thư viện đang được đo điểm chuẩn) không dành riêng cho PGO và nằm ngoài phạm vi của tài liệu này.
- Truyền nhanh hoặc đồng bộ hoá bản dựng được đo lường trên một thiết bị.
- Chạy phép đo điểm chuẩn để thu thập hồ sơ.
- Sử dụng công cụ
llvm-profdata
(xem phần thảo luận bên dưới) để xử lý sau các hồ sơ và chuẩn bị để kiểm tra các hồ sơ đó vào cây nguồn.
Sử dụng hồ sơ trong quá trình tạo bản dựng
Kiểm tra các hồ sơ vào toolchain/pgo-profiles
trong cây Android. Tên phải khớp với tên được chỉ định trong thuộc tính phụ profile_file
của thuộc tính pgo
cho thư viện. Hệ thống xây dựng sẽ tự động chuyển tệp hồ sơ đến Clang khi tạo thư viện. Bạn có thể đặt biến môi trường ANDROID_PGO_DISABLE_PROFILE_USE
thành true
để tạm thời tắt PGO và đo lường lợi ích về hiệu suất của PGO.
Để chỉ định các thư mục hồ sơ bổ sung theo sản phẩm, hãy thêm các thư mục đó vào biến tạo PGO_ADDITIONAL_PROFILE_DIRECTORIES
trong BoardConfig.mk
. Nếu bạn chỉ định các đường dẫn bổ sung, thì các hồ sơ trong các đường dẫn này sẽ ghi đè các hồ sơ trong toolchain/pgo-profiles
.
Khi tạo hình ảnh phát hành bằng cách sử dụng mục tiêu dist
cho make
, hệ thống xây dựng sẽ ghi tên của các tệp hồ sơ bị thiếu vào $DIST_DIR/pgo_profile_file_missing.txt
. Bạn có thể kiểm tra tệp này để xem những tệp hồ sơ nào đã bị vô tình xoá (tắt PGO một cách thầm lặng).
Bật PGO trong tệp Android.bp
Để bật PGO trong tệp Android.bp
cho các mô-đun gốc, bạn chỉ cần chỉ định thuộc tính pgo
. Thuộc tính này có các thuộc tính phụ sau:
Thuộc tính | Nội dung mô tả |
---|---|
instrumentation
|
Đặt thành true cho PGO bằng cách sử dụng tính năng đo lường. Giá trị mặc định là false . |
sampling
|
Đặt thành true cho PGO bằng cách sử dụng tính năng lấy mẫu. Giá trị mặc định là false . |
benchmarks
|
Danh sách chuỗi. Mô-đun này được tạo để lập hồ sơ nếu có điểm chuẩn nào trong danh sách được chỉ định trong tuỳ chọn bản dựng ANDROID_PGO_INSTRUMENT . |
profile_file
|
Tệp hồ sơ (so với toolchain/pgo-profile ) để sử dụng với PGO. Bản dựng sẽ cảnh báo rằng tệp này không tồn tại bằng cách thêm tệp này vào $DIST_DIR/pgo_profile_file_missing.txt
trừ phi thuộc tính enable_profile_use được đặt thành false HOẶC biến bản dựng ANDROID_PGO_NO_PROFILE_USE được đặt thành true . |
enable_profile_use
|
Đặt thành false nếu không nên sử dụng hồ sơ trong quá trình tạo bản dựng. Có thể dùng trong quá trình khởi động để bật tính năng thu thập hồ sơ hoặc để tạm thời tắt PGO. Giá trị mặc định là true . |
cflags
|
Danh sách các cờ bổ sung để sử dụng trong bản dựng được đo lường. |
Ví dụ về mô-đun có PGO:
cc_library { name: "libexample", srcs: [ "src1.cpp", "src2.cpp", ], static: [ "libstatic1", "libstatic2", ], shared: [ "libshared1", ] pgo: { instrumentation: true, benchmarks: [ "benchmark1", "benchmark2", ], profile_file: "example.profdata", } }
Nếu điểm chuẩn benchmark1
và benchmark2
thực hiện hành vi đại diện cho các thư viện libstatic1
, libstatic2
hoặc libshared1
, thì thuộc tính pgo
của các thư viện này cũng có thể bao gồm các điểm chuẩn. Mô-đun defaults
trong Android.bp
có thể bao gồm một thông số kỹ thuật pgo
chung cho một nhóm thư viện để tránh lặp lại cùng một quy tắc bản dựng cho một số mô-đun.
Để chọn các tệp cấu hình khác nhau hoặc tắt PGO một cách có chọn lọc cho một cấu trúc, hãy chỉ định các thuộc tính profile_file
, enable_profile_use
và cflags
cho mỗi cấu trúc. Ví dụ (với mục tiêu cấu trúc được in nổi):
cc_library { name: "libexample", srcs: [ "src1.cpp", "src2.cpp", ], static: [ "libstatic1", "libstatic2", ], shared: [ "libshared1", ], pgo: { instrumentation: true, benchmarks: [ "benchmark1", "benchmark2", ], } target: { android_arm: { pgo: { profile_file: "example_arm.profdata", } }, android_arm64: { pgo: { profile_file: "example_arm64.profdata", } } } }
Để phân giải các tệp tham chiếu đến thư viện thời gian chạy phân tích tài nguyên trong quá trình phân tích tài nguyên dựa trên đo lường, hãy truyền cờ bản dựng -fprofile-generate
đến trình liên kết. Thư viện tĩnh được đo lường bằng PGO, tất cả thư viện dùng chung và mọi tệp nhị phân trực tiếp phụ thuộc vào thư viện tĩnh cũng phải được đo lường cho PGO. Tuy nhiên, các thư viện hoặc tệp thực thi dùng chung như vậy không cần sử dụng hồ sơ PGO và bạn có thể đặt thuộc tính enable_profile_use
của các thư viện đó thành false
.
Ngoài quy định hạn chế này, bạn có thể áp dụng PGO cho mọi thư viện tĩnh, thư viện dùng chung hoặc tệp thực thi.
Xử lý tệp hồ sơ LLVM
Việc thực thi một thư viện được đo lường hoặc tệp thực thi sẽ tạo ra một tệp cấu hình có tên là default_unique_id_0.profraw
trong /data/local/tmp
(trong đó unique_id
là một hàm băm số chỉ dành riêng cho thư viện này). Nếu tệp này đã tồn tại, thời gian chạy phân tích tài nguyên sẽ hợp nhất hồ sơ mới với hồ sơ cũ trong khi ghi hồ sơ. Xin lưu ý rằng nhà phát triển ứng dụng không thể truy cập vào /data/local/tmp
; thay vào đó, họ nên sử dụng một nơi nào đó như /storage/emulated/0/Android/data/packagename/files
.
Để thay đổi vị trí của tệp cấu hình, hãy đặt biến môi trường LLVM_PROFILE_FILE
trong thời gian chạy.
Sau đó, tiện ích llvm-profdata
được dùng để chuyển đổi tệp .profraw
(và có thể hợp nhất nhiều tệp .profraw
) thành tệp .profdata
:
llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>
Sau đó, bạn có thể kiểm tra profile.profdata
vào cây nguồn để sử dụng trong quá trình xây dựng.
Nếu nhiều tệp nhị phân/thư viện được đo lường được tải trong quá trình đo điểm chuẩn, thì mỗi thư viện sẽ tạo một tệp .profraw
riêng biệt với một mã nhận dạng duy nhất riêng biệt. Thông thường, tất cả các tệp này có thể được hợp nhất thành một tệp .profdata
duy nhất và được dùng cho bản dựng PGO. Trong trường hợp một thư viện được thực thi bằng một điểm chuẩn khác, thư viện đó phải được tối ưu hoá bằng cách sử dụng hồ sơ của cả hai điểm chuẩn. Trong trường hợp này, tuỳ chọn show
của llvm-profdata
sẽ hữu ích:
llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw llvm-profdata show -all-functions default_unique_id.profdata
Để liên kết unique_id với từng thư viện, hãy tìm tên hàm duy nhất của thư viện trong kết quả show
cho mỗi unique_id.
Nghiên cứu điển hình: PGO cho ART
Nghiên cứu điển hình này trình bày ART dưới dạng một ví dụ có thể liên tưởng; tuy nhiên, đây không phải là mô tả chính xác về tập hợp thư viện thực tế được lập hồ sơ cho ART hoặc các mối tương quan phụ thuộc lẫn nhau của chúng.
Trình biên dịch trước thời gian dex2oat
trong ART phụ thuộc vào libart-compiler.so
, rồi phụ thuộc vào libart.so
. Thời gian chạy ART chủ yếu được triển khai trong libart.so
. Các điểm chuẩn cho trình biên dịch và thời gian chạy sẽ khác nhau:
Điểm chuẩn | Thư viện được phân tích tài nguyên |
---|---|
dex2oat
|
dex2oat (có thể thực thi), libart-compiler.so ,
libart.so |
art_runtime
|
libart.so
|
- Thêm thuộc tính
pgo
sau vàodex2oat
,libart-compiler.so
:pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", }
- Thêm thuộc tính
pgo
sau vàolibart.so
:pgo: { instrumentation: true, benchmarks: ["art_runtime", "dex2oat",], profile_file: "libart.profdata", }
- Tạo bản dựng được đo lường cho điểm chuẩn
dex2oat
vàart_runtime
bằng cách sử dụng:make ANDROID_PGO_INSTRUMENT=dex2oat make ANDROID_PGO_INSTRUMENT=art_runtime
- Chạy phép đo điểm chuẩn thực thi
dex2oat
vàart_runtime
để lấy:- Ba tệp
.profraw
từdex2oat
(dex2oat_exe.profdata
,dex2oat_libart-compiler.profdata
vàdexeoat_libart.profdata
), được xác định bằng phương thức được mô tả trong phần Xử lý tệp hồ sơ LLVM. - Một
art_runtime_libart.profdata
.
- Ba tệp
- Tạo một tệp profdata chung cho
dex2oat
có thể thực thi vàlibart-compiler.so
bằng cách sử dụng:llvm-profdata merge -output=dex2oat.profdata \ dex2oat_exe.profdata dex2oat_libart-compiler.profdata
- Lấy hồ sơ cho
libart.so
bằng cách hợp nhất các hồ sơ từ hai điểm chuẩn:llvm-profdata merge -output=libart.profdata \ dex2oat_libart.profdata art_runtime_libart.profdata
Số lượng thô của
libart.so
từ hai hồ sơ có thể khác nhau vì các điểm chuẩn khác nhau về số lượng trường hợp kiểm thử và thời lượng chạy. Trong trường hợp này, bạn có thể sử dụng tính năng hợp nhất có trọng số:llvm-profdata merge -output=libart.profdata \ -weighted-input=2,dex2oat_libart.profdata \ -weighted-input=1,art_runtime_libart.profdata
Lệnh trên gán trọng số gấp đôi cho hồ sơ từ
dex2oat
. Trọng số thực tế phải được xác định dựa trên kiến thức về miền hoặc thử nghiệm. - Kiểm tra các tệp cấu hình
dex2oat.profdata
vàlibart.profdata
vàotoolchain/pgo-profiles
để sử dụng trong quá trình xây dựng.
Ngoài ra, hãy tạo một bản dựng được đo lường duy nhất với tất cả thư viện được đo lường bằng cách sử dụng:
make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime (or) make ANDROID_PGO_INSTRUMENT=ALL
Lệnh thứ hai tạo tất cả mô-đun hỗ trợ PGO để phân tích tài nguyên.