Hệ thống xây dựng Android dành cho Android 13 trở xuống hỗ trợ bằng cách sử dụng cấu hình hướng dẫn của Clang tối ưu hoá (PGO) trên các mô-đun Android gốc có bản dựng bản vẽ quy tắc. 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 và cách tích hợp PGO với hệ thống xây dựng (với 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, truy cập trang này.
Giới thiệu về Clang PGO
Clang có thể thực hiện tối ưu hoá theo cấu hình bằng 2 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 được nêu chi tiết và đặt trong thời gian chạy.
- Hồ sơ dựa trên lấy mẫu thường được tạo bởi bộ đếm phần cứng lấy mẫu. Chúng đòi hỏi mức hao tổn thấp trong thời gian chạy và có thể được thu thập mà không có bất kỳ đo lường hay sửa đổi nào đối với tệp nhị phân. Chúng ít chi tiết hơn so với hồ sơ dựa trên đo lường.
Tất cả hồ sơ phải được tạo từ một khối lượng công việc đại diện
thực thi hành vi điển hình 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)
, Android chỉ hỗ trợ dựa trên LLVM IR cho
PGO dựa trên khả năng đo lường.
Cần có các cờ sau để tạo bộ sưu tập hồ sơ:
-fprofile-generate
để đo lường dựa trên hồng ngoại. Bằng cách này , phần phụ trợ sử dụng phương pháp cây bao trùm 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 chúng để 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). Clang trình điều khiển tự động vượt qua thời gian chạy lập hồ sơ (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 theo chương trình thoát.-gline-tables-only
để thu thập hồ sơ dựa trên việc lấy mẫu để tạo thông tin gỡ lỗi tối thiểu.
Hồ sơ có thể được dùng cho PGO bằng cách sử dụng
-fprofile-use=pathname
hoặc
-fprofile-sample-use=pathname
đối với phương pháp dựa trên khả năng đo lường
và hồ sơ dựa trên lấy mẫu tương ứng.
Lưu ý: Khi mã được thay đổi, nếu Clang không thể
sử dụng dữ liệu hồ sơ mà công cụ tạo
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 bằng 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 đại diện trên tệp nhị phân được đo lường.
- Hậu xử lý các hồ sơ bằng tiện ích
llvm-profdata
(để biết thông tin chi tiết, hãy xem bài viết Xử lý LLVM tệp cấu hình). - Sử dụng các hồ sơ để á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, hồ sơ phải được thu thập ngoại tuyến và đăng ký cùng với mã để đảm bảo các bản dựng có thể tái tạo. Các hồ sơ này có thể được dùng làm mã phát triển nhưng phải được tạo lại theo định kỳ (hoặc bất cứ khi nào Clang cảnh báo rằng các cấu hình đã cũ).
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 các 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 điểm chuẩn sẽ được chạy. Tại thời điểm này, Android không hỗ trợ việc sử dụng phương thức lấy mẫu bộ sưu tập hồ sơ, vì vậy, bạn phải thu thập các hồ sơ bằng cách sử dụng một bản dựng:
- Xác định điểm chuẩn và tập hợp thư viện được thực hiện chung bằng điểm chuẩn đó.
- Thêm 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 bằng bản sao đo lường của các thư viện này
sử dụng:
make ANDROID_PGO_INSTRUMENT=benchmark
benchmark
là một phần giữ chỗ giúp xác định
tập hợp thư viện được đo lường trong quá trình tạo bản dựng. Người đại diện thực tế
đầu vào (và có thể một tệp thực thi khác liên kết với một thư viện đang
đ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.
- Cài đặt ROM hoặc đồng bộ hoá bản dựng được đo lường trên 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
(sẽ thảo luận bên dưới) để hậu xử lý hồ sơ và làm cho chúng sẵn sàng để được kiểm tra vào nguồn cây xanh.
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 Android
cây xanh. Tên phải khớp với tên được chỉ định trong
Tài sản phụ profile_file
của tài sản pgo
cho
thư viện. Hệ thống xây dựng tự động chuyển tệp hồ sơ đến Clang
khi xây dựng thư viện. ANDROID_PGO_DISABLE_PROFILE_USE
biến môi trường có thể được đặt thành true
thành
tạm thời vô hiệu hoá PGO và đo lường lợi ích về hiệu suất của PGO.
Để chỉ định thư mục hồ sơ bổ sung dành riêng cho sản phẩm, hãy gắn các thư mục đó vào
biến tạo PGO_ADDITIONAL_PROFILE_DIRECTORIES
trong một
BoardConfig.mk
Nếu đường dẫn bổ sung được chỉ định, các cấu hình trong
các đường dẫn này sẽ ghi đè các đường dẫn trong toolchain/pgo-profiles
.
Khi tạo hình ảnh bản phát hành bằng cách sử dụng mục tiêu dist
để
make
, hệ thống xây dựng ghi tên của các tệp hồ sơ bị thiếu
đến $DIST_DIR/pgo_profile_file_missing.txt
. Bạn có thể kiểm tra
để xem tệp hồ sơ nào vô tình bị thả (các tệp này tự động bị xoá
vô hiệu hoá PGO).
Bật PGO trong tệp Android.bp
Để bật PGO trong tệp Android.bp
cho các mô-đun gốc, chỉ cần
chỉ định thuộc tính pgo
. Cơ sở lưu trú này có:
thuộc tính phụ:
Thuộc tính | Mô tả |
---|---|
instrumentation
|
Đặt thành true cho PGO bằng cách sử dụng khả năng đo lường. Mặc định là
false . |
sampling
|
Đặt thành true cho PGO sử dụng phương thức lấy mẫu. Mặc định là
false . |
benchmarks
|
Danh sách chuỗi. Mô-đun này được xây dựng để phân tích nếu có bất kỳ điểm chuẩn nào
trong danh sách được chỉ định trong bản dựng ANDROID_PGO_INSTRUMENT
. |
profile_file
|
Tệp cấu hình (tương đối so với toolchain/pgo-profile ) để sử dụng
cùng PGO. Bản dựng 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
tệp vào $DIST_DIR/pgo_profile_file_missing.txt
trừ khi 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 khoảng thời gian
bản dựng. Có thể được sử dụng trong quá trình Tự thân khởi nghiệp để bật thu thập hồ sơ hoặc để
tạm thời tắt PGO. Mặc định là true . |
cflags
|
Danh sách cờ bổ sung để sử dụng trong một bản dựng được đo lường. |
Ví dụ về một 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
hành vi đại diện tập thể dục cho thư viện libstatic1
,
libstatic2
hay libshared1
, pgo
của các thư viện này cũng có thể bao gồm các điểm chuẩn. Chiến lược phát hành đĩa đơn
Mô-đun defaults
trong Android.bp
có thể bao gồm một thuộc tính chung
Thông số pgo
cho một nhóm thư viện để tránh lặp lại
cùng một quy tắc xây dựng
cho một số mô-đun.
Để chọn các tệp cấu hình khác nhau hoặc vô hiệu hoá có chọn lọc PGO cho một
cấu trúc, chỉ định profile_file
,
enable_profile_use
và cflags
thuộc tính mỗi
cấu trúc. Ví dụ (với mục tiêu cấu trúc trong
in đậm):
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 tham chiếu đến thư viện thời gian chạy lập hồ sơ trong
lập hồ sơ dựa trên khả năng đo lường, 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
với PGO, tất cả thư viện dùng chung và bất kỳ tệp nhị phân nào phụ thuộc trực tiếp vào
thư viện tĩnh cũng phải được đo lường cho PGO. Tuy nhiên, việc chia sẻ như vậy
thư viện hoặc tệp thực thi không cần phải sử dụng cấu hình PGO và
Bạn có thể đặt thuộc tính enable_profile_use
thành false
.
Ngoài hạn chế này, bạn có thể áp dụng PGO cho mọi thư viện tĩnh được chia sẻ
thư viện hoặc tệp thực thi.
Xử lý các tệp cấu hình 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 default_unique_id_0.profraw
ở
/data/local/tmp
(trong đó unique_id
là một
băm số duy nhất cho thư viện này). Nếu tệp này đã tồn tại,
thời gian chạy hồ sơ hợp nhất hồ sơ mới với hồ sơ cũ trong khi viết
các hồ sơ. Lưu ý rằng ứng dụng không thể truy cập vào /data/local/tmp
nhà phát triển; chẳng hạn như
Hãy /storage/emulated/0/Android/data/packagename/files
.
Để thay đổi vị trí của tệp cấu hình, hãy đặt LLVM_PROFILE_FILE
trong thời gian chạy.
llvm-profdata
sau đó tiện ích được dùng để chuyển đổi tệp .profraw
(và có thể
hợp nhất nhiều tệp .profraw
) vào một .profdata
tệp:
llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>
Sau đó, bạn có thể kiểm tra profile.profdata
trong nguồn
để sử dụng trong quá trình tạo bản 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,
mỗi thư viện sẽ tạo một tệp .profraw
riêng có một tệp riêng
mã nhận dạng duy nhất. Thông thường, có thể hợp nhất tất cả các tệp này thành một tệp duy nhất
.profdata
và được dùng cho bản dựng PGO. Trong trường hợp thư viện
được thực thi bởi một điểm chuẩn khác, thì thư viện đó phải được tối ưu hoá bằng cách sử dụng
hồ sơ từ cả hai điểm chuẩn. Trong trường hợp này, show
lựa chọn 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 các thư viện riêng lẻ, hãy tìm kiếm
Đầu ra show
cho mỗi Unique_id của một tên hàm
là duy nhất đối với thư viện.
Nghiên cứu điển hình: PGO cho ART
Nghiên cứu điển hình này cho thấy ART là một ví dụ gần gũi; tuy nhiên, tính năng này không phải là thông tin mô tả chính xác tập hợp thư viện thực tế được lập hồ sơ cho ART hoặc sự phụ thuộc lẫn nhau của chúng.
Trình biên dịch trước khi chạy dex2oat
trong ART phụ thuộc vào
libart-compiler.so
, do đó phụ thuộc vào
libart.so
. Môi trường thời gian chạy ART được triển khai chủ yếu trong
libart.so
. Điểm chuẩn cho trình biên dịch và thời gian chạy sẽ là
khác nhau:
Điểm chuẩn | Thư viện đã 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 các bản dựng được đo lường cho
dex2oat
vàart_runtime
điểm chuẩn 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 hiện
dex2oat
vàart_runtime
để nhận:- 3 tệp
.profraw
trongdex2oat
(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ý hồ sơ LLVM . - Một
art_runtime_libart.profdata
.
- 3 tệp
- Tạo một tệp profdata chung cho
dex2oat
có thể thực thi vàlibart-compiler.so
đang 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ừ 2 đ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 cấu hình có thể là khác nhau vì điểm chuẩn khác nhau về số lượng trường hợp kiểm thử và thời lượng chúng chạy. Trong trường hợp này, bạn có thể sử dụ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 chỉ định trọng số gấp đôi cho cấu hình từ
dex2oat
. Trọng số thực tế phải được xác định dựa trên miền kiến thức hoặc thử nghiệm. - Kiểm tra các tệp hồ sơ
dex2oat.profdata
vàlibart.profdata
sangtoolchain/pgo-profiles
cho trong quá trình tạo.
Ngoài ra, hãy tạo một bản dựng được đo lường với tất cả các thư viện đo lường bằ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 cho lập hồ sơ.