Sử dụng tính năng tối ưu hoá theo cấu hình

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:

  1. 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.
  2. 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.
  3. 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).
  4. 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:

  1. 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 đó.
  2. 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).
  3. 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.

  1. Cài đặt ROM hoặc đồng bộ hoá bản dựng được đo lường trên thiết bị.
  2. Chạy phép đo điểm chuẩn để thu thập hồ sơ.
  3. 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 benchmark1benchmark2 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_usecflags 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
  1. Thêm thuộc tính pgo sau vào dex2oat libart-compiler.so:
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. Thêm thuộc tính pgo sau vào libart.so:
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. Tạo các bản dựng được đo lường cho dex2oatart_runtime điểm chuẩn sử dụng:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. 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ơ.

  5. Chạy phép đo điểm chuẩn thực hiện dex2oatart_runtime để nhận:
    • 3 tệp .profraw trong dex2oat (dex2oat_exe.profdata, dex2oat_libart-compiler.profdatadexeoat_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.
  6. 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
  7. 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.

  8. Kiểm tra các tệp hồ sơ dex2oat.profdatalibart.profdata sang toolchain/pgo-profiles cho trong quá trình tạo.