ระบบการสร้างของ Android สำหรับ Android 13 และต่ำกว่ารองรับการใช้การเพิ่มประสิทธิภาพโดยอิงตามโปรไฟล์ (PGO) ของ Clang ในโมดูล Android เนทีฟที่มีกฎการสร้าง blueprint หน้านี้อธิบาย Clang PGO, วิธีสร้างและอัปเดตโปรไฟล์ที่ใช้สำหรับ PGO อย่างต่อเนื่อง และวิธีผสานรวม PGO กับระบบการบิลด์ (พร้อมกรณีการใช้งาน)
หมายเหตุ: เอกสารนี้อธิบายการใช้ PGO ในแพลตฟอร์ม Android ดูข้อมูลเกี่ยวกับการใช้ PGO จากแอป Android ได้ที่ หน้านี้
เกี่ยวกับ Clang PGO
Clang สามารถทำการเพิ่มประสิทธิภาพโดยอิงตามโปรไฟล์ได้โดยใช้โปรไฟล์ 2 ประเภทดังนี้
- โปรไฟล์ที่อิงตามเครื่องมือวัดสร้างขึ้นจากโปรแกรมเป้าหมายที่มีเครื่องมือวัด โปรไฟล์เหล่านี้มีรายละเอียดสูงและทำให้เกิดค่าใช้จ่ายเพิ่มเติมในรันไทม์
- โปรไฟล์ที่อิงตามการสุ่มตัวอย่างมักสร้างขึ้นโดยเคาน์เตอร์ฮาร์ดแวร์การสุ่มตัวอย่าง ข้อมูลเหล่านี้มีค่าใช้จ่ายรันไทม์ต่ำและรวบรวมได้โดยไม่ต้องมีเครื่องมือวัดผลหรือการแก้ไขไบนารี โปรไฟล์เหล่านี้มีรายละเอียดน้อยกว่าโปรไฟล์ที่อิงตามเครื่องมือวัด
โปรไฟล์ทั้งหมดควรสร้างขึ้นจากภาระงานที่แสดงถึงลักษณะการทำงานทั่วไปของแอป แม้ว่า Clang จะรองรับทั้งแบบที่อิงตาม AST (-fprofile-instr-generate
) และแบบที่อิงตาม LLVM IR (-fprofile-generate)
แต่ Android รองรับเฉพาะแบบที่อิงตาม LLVM IR สำหรับ PGO ที่อิงตามเครื่องมือวัด
คุณต้องสร้าง Flag ต่อไปนี้สําหรับการเก็บรวบรวมโปรไฟล์
-fprofile-generate
สำหรับเครื่องมือวัดที่ใช้ IR เมื่อใช้ตัวเลือกนี้ แบ็กเอนด์จะใช้แนวทางต้นไม้สายเชื่อมขั้นต่ำที่มีน้ำหนักเพื่อลดจํานวนจุดเครื่องมือวัดและเพิ่มประสิทธิภาพตําแหน่งจุดเครื่องมือวัดไปยังขอบที่มีน้ำหนักเบา (ใช้ตัวเลือกนี้สําหรับขั้นตอนลิงก์ด้วย) โปรแกรมขับ Clang จะส่งรันไทม์การโปรไฟล์ (libclang_rt.profile-arch-android.a
) ไปยังโปรแกรมลิงก์โดยอัตโนมัติ ไลบรารีนี้มีกิจวัตรในการเขียนโปรไฟล์ลงในดิสก์เมื่อโปรแกรมออก-gline-tables-only
สําหรับการเก็บรวบรวมโปรไฟล์ที่อิงตามการสุ่มตัวอย่างเพื่อสร้างข้อมูลการแก้ไขข้อบกพร่องขั้นต่ำ
คุณสามารถใช้โปรไฟล์สําหรับ PGO ได้โดยใช้ -fprofile-use=pathname
หรือ -fprofile-sample-use=pathname
สําหรับโปรไฟล์ที่อิงตามเครื่องมือวัดผลและโปรไฟล์ที่อิงตามการสุ่มตัวอย่างตามลําดับ
หมายเหตุ: เมื่อทำการเปลี่ยนแปลงโค้ด หาก Clang ใช้ข้อมูลโปรไฟล์ไม่ได้อีกต่อไป ก็จะสร้างคำเตือน -Wprofile-instr-out-of-date
ใช้ PGO
การใช้ PGO มีขั้นตอนดังนี้
- สร้างไลบรารี/ไฟล์ปฏิบัติการที่มีเครื่องมือวัดโดยการส่ง
-fprofile-generate
ไปยังคอมไพเลอร์และโปรแกรมลิงก์ - รวบรวมโปรไฟล์โดยเรียกใช้เวิร์กโหลดที่แสดงถึงในไบนารีที่มีเครื่องมือวัด
- ประมวลผลโปรไฟล์ในขั้นตอนหลังโดยใช้ยูทิลิตี
llvm-profdata
(โปรดดูรายละเอียดที่หัวข้อการจัดการไฟล์โปรไฟล์ LLVM) - ใช้โปรไฟล์เพื่อใช้ PGO โดยส่ง
-fprofile-use=<>.profdata
ไปยังคอมไพเลอร์และโปรแกรมลิงก์
สำหรับ PGO ใน Android คุณควรรวบรวมโปรไฟล์แบบออฟไลน์และตรวจสอบพร้อมกับโค้ดเพื่อให้แน่ใจว่าบิลด์จะสร้างซ้ำได้ โปรไฟล์นี้ใช้ได้เมื่อโค้ดมีการเปลี่ยนแปลง แต่ต้องสร้างใหม่เป็นระยะๆ (หรือเมื่อใดก็ตามที่ Clang เตือนว่าโปรไฟล์ล้าสมัย)
รวบรวมโปรไฟล์
Clang สามารถใช้โปรไฟล์ที่รวบรวมโดยการเรียกใช้การทดสอบประสิทธิภาพโดยใช้บิลด์ที่เครื่องมือวัดของไลบรารี หรือโดยการสุ่มตัวอย่างตัวนับฮาร์ดแวร์เมื่อเรียกใช้การทดสอบประสิทธิภาพ ขณะนี้ Android ไม่รองรับการใช้การเก็บรวบรวมโปรไฟล์ที่อิงตามการสุ่มตัวอย่าง คุณจึงต้องรวบรวมโปรไฟล์โดยใช้บิลด์ที่มีเครื่องมือวัดผล ดังนี้
- ระบุการเปรียบเทียบและชุดไลบรารีที่ใช้ร่วมกันโดยข้อมูลเปรียบเทียบนั้น
- เพิ่มพร็อพเพอร์ตี้
pgo
ลงในการเปรียบเทียบและไลบรารี (ดูรายละเอียดด้านล่าง) - สร้างบิลด์ Android ที่มีสำเนาที่เครื่องมือวัดประสิทธิภาพของไลบรารีเหล่านี้โดยใช้
make ANDROID_PGO_INSTRUMENT=benchmark
benchmark
คือตัวยึดตําแหน่งซึ่งระบุคอลเล็กชันของไลบรารีที่ใช้เครื่องมือวัดระหว่างการสร้าง อินพุตตัวแทนจริง (และอาจเป็นไฟล์ที่เรียกใช้งานได้อีกไฟล์หนึ่งที่ลิงก์กับไลบรารีที่ทำการเปรียบเทียบประสิทธิภาพ) ไม่ได้เจาะจงสำหรับ PGO และอยู่นอกขอบเขตของเอกสารนี้
- แฟลชหรือซิงค์บิลด์ที่มีเครื่องมือวัดผลในอุปกรณ์
- เรียกใช้การเปรียบเทียบเพื่อรวบรวมโปรไฟล์
- ใช้เครื่องมือ
llvm-profdata
(ตามที่อธิบายไว้ด้านล่าง) เพื่อประมวลผลโปรไฟล์ในขั้นตอนหลัง และทำให้พร้อมที่จะตรวจสอบในทรีแหล่งที่มา
ใช้โปรไฟล์ระหว่างการบิลด์
ตรวจสอบโปรไฟล์ใน toolchain/pgo-profiles
ในทรี Android
ชื่อควรตรงกับที่ระบุไว้ในพร็อพเพอร์ตี้ย่อย profile_file
ของพร็อพเพอร์ตี้ pgo
สำหรับห้องสมุด ระบบบิลด์จะส่งไฟล์โปรไฟล์ไปยัง Clang โดยอัตโนมัติเมื่อสร้างไลบรารี คุณสามารถตั้งค่าตัวแปรสภาพแวดล้อม ANDROID_PGO_DISABLE_PROFILE_USE
เป็น true
เพื่อปิดใช้ PGO ชั่วคราวและวัดผลลัพธ์ด้านประสิทธิภาพ
หากต้องการระบุไดเรกทอรีโปรไฟล์เฉพาะผลิตภัณฑ์เพิ่มเติม ให้เพิ่มไดเรกทอรีนั้นต่อท้ายPGO_ADDITIONAL_PROFILE_DIRECTORIES
make variable in a
BoardConfig.mk
หากระบุเส้นทางเพิ่มเติม โปรไฟล์ในเส้นทางเหล่านี้จะลบล้างโปรไฟล์ใน toolchain/pgo-profiles
เมื่อสร้างภาพรุ่นโดยใช้เป้าหมาย dist
ไปยัง make
ระบบบิลด์จะเขียนชื่อไฟล์โปรไฟล์ที่ขาดหายไปลงใน $DIST_DIR/pgo_profile_file_missing.txt
คุณสามารถตรวจสอบไฟล์นี้เพื่อดูว่าไฟล์โปรไฟล์ใดถูกลบโดยไม่ตั้งใจ (ซึ่งจะปิดใช้ PGO โดยอัตโนมัติ)
เปิดใช้ PGO ในไฟล์ Android.bp
หากต้องการเปิดใช้ PGO ในไฟล์ Android.bp
สำหรับโมดูลที่มาพร้อมระบบ ให้ระบุพร็อพเพอร์ตี้ pgo
พร็อพเพอร์ตี้นี้มีพร็อพเพอร์ตี้ย่อยต่อไปนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
instrumentation
|
ตั้งค่าเป็น true สำหรับ PGO โดยใช้เครื่องมือวัด ค่าเริ่มต้นคือ false |
sampling
|
ตั้งค่าเป็น true สำหรับ PGO โดยใช้การสุ่มตัวอย่าง ค่าเริ่มต้นคือ false |
benchmarks
|
รายการสตริง โมดูลนี้สร้างขึ้นเพื่อโปรไฟล์หากมีการระบุการเปรียบเทียบในรายการในตัวเลือก ANDROID_PGO_INSTRUMENT build
|
profile_file
|
ไฟล์โปรไฟล์ (สัมพันธ์กับ toolchain/pgo-profile ) เพื่อใช้กับ PGO บิลด์จะเตือนว่าไม่มีไฟล์นี้โดยการเพิ่มไฟล์นี้ลงใน $DIST_DIR/pgo_profile_file_missing.txt
เว้นแต่จะมีการตั้งค่าพร็อพเพอร์ตี้ enable_profile_use เป็น
false หรือมีการตั้งค่าตัวแปรบิลด์ ANDROID_PGO_NO_PROFILE_USE เป็น
true |
enable_profile_use
|
ตั้งค่าเป็น false หากไม่ควรใช้โปรไฟล์ระหว่างการสร้าง ใช้ในระหว่างการเริ่มต้นระบบเพื่อเปิดใช้การเก็บรวบรวมโปรไฟล์หรือปิดใช้ PGO ชั่วคราวได้ ค่าเริ่มต้นคือ true |
cflags
|
รายการ Flag เพิ่มเติมที่จะใช้ในระหว่างการสร้างที่มีการวัดผล |
ตัวอย่างโมดูลที่มี 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", } }
หากการเปรียบเทียบ benchmark1
และ benchmark2
ใช้ลักษณะการทำงานที่เป็นตัวแทนสำหรับไลบรารี libstatic1
, libstatic2
หรือ libshared1
พร็อพเพอร์ตี้ pgo
ของไลบรารีเหล่านี้จะรวมการเปรียบเทียบดังกล่าวด้วย โมดูล defaults
ใน Android.bp
สามารถระบุข้อกำหนด pgo
ทั่วไปสำหรับชุดไลบรารีเพื่อหลีกเลี่ยงการใช้กฎการสร้างเดียวกันซ้ำหลายครั้งสำหรับโมดูลต่างๆ
หากต้องการเลือกไฟล์โปรไฟล์อื่นหรือปิดใช้ PGO แบบเลือกสำหรับสถาปัตยกรรม ให้ระบุพร็อพเพอร์ตี้ profile_file
, enable_profile_use
และ cflags
ตามสถาปัตยกรรม ตัวอย่าง (โดยมีเป้าหมายสถาปัตยกรรมเป็นตัวหนา)
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", } } } }
หากต้องการแก้ไขการอ้างอิงถึงไลบรารีรันไทม์ของเครื่องมือวิเคราะห์ระหว่างการโปรไฟล์ตามเครื่องมือวัด ให้ส่ง Flag การสร้าง -fprofile-generate
ไปยังโปรแกรมลิงก์ ไลบรารีแบบคงที่ที่มีเครื่องมือ PGO, ไลบรารีที่ใช้ร่วมกันทั้งหมด และไบนารีที่ขึ้นต่อกันกับไลบรารีแบบคงที่โดยตรงจะต้องมีเครื่องมือ PGO ด้วย อย่างไรก็ตาม ห้องสมุดหรือไฟล์ปฏิบัติการที่แชร์ดังกล่าวไม่จำเป็นต้องใช้โปรไฟล์ PGO และสามารถตั้งค่าพร็อพเพอร์ตี้ enable_profile_use
เป็น false
ได้
นอกเหนือจากข้อจำกัดนี้ คุณสามารถใช้ PGO กับไลบรารีแบบคงที่ ไลบรารีที่ใช้ร่วมกัน หรือไฟล์ปฏิบัติการได้
จัดการไฟล์โปรไฟล์ LLVM
การดำเนินการกับไลบรารีหรือไฟล์ที่เรียกใช้งานได้จะสร้างไฟล์โปรไฟล์ชื่อ default_unique_id_0.profraw
ใน /data/local/tmp
(โดยที่ unique_id
คือแฮชตัวเลขที่ไม่ซ้ำกันสำหรับไลบรารีนี้) หากมีไฟล์นี้อยู่แล้ว รันไทม์การโปรไฟล์จะผสานโปรไฟล์ใหม่เข้ากับโปรไฟล์เก่าขณะเขียนโปรไฟล์ โปรดทราบว่านักพัฒนาแอปไม่สามารถเข้าถึง /data/local/tmp
ได้ แต่ควรใช้ /storage/emulated/0/Android/data/packagename/files
แทน
หากต้องการเปลี่ยนตำแหน่งของไฟล์โปรไฟล์ ให้ตั้งค่าตัวแปรสภาพแวดล้อม LLVM_PROFILE_FILE
ขณะรันไทม์
จากนั้นจะใช้ยูทิลิตี llvm-profdata
เพื่อแปลงไฟล์ .profraw
(และอาจรวมไฟล์ .profraw
หลายไฟล์) เป็นไฟล์ .profdata
ดังนี้
llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>
จากนั้นจึงจะเช็คอิน profile.profdata
ลงในซอร์สทรีเพื่อใช้ในระหว่างการสร้างได้
หากโหลดไบนารี/ไลบรารีที่มีเครื่องมือวัดหลายรายการระหว่างการทดสอบประสิทธิภาพ ไลบรารีแต่ละรายการจะสร้างไฟล์ .profraw
แยกต่างหากที่มีรหัสที่ไม่ซ้ำกัน โดยปกติแล้ว ไฟล์เหล่านี้ทั้งหมดจะผสานเป็นไฟล์ .profdata
ไฟล์เดียวได้และใช้สำหรับบิลด์ PGO ในกรณีที่มีการใช้ไลบรารีในเบนช์มาร์กอื่น ไลบรารีนั้นจะต้องได้รับการเพิ่มประสิทธิภาพโดยใช้โปรไฟล์จากทั้ง 2 เบนช์มาร์ก ในกรณีนี้ ตัวเลือก show
ของ llvm-profdata
จะมีประโยชน์
llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw llvm-profdata show -all-functions default_unique_id.profdata
หากต้องการแมป unique_id กับไลบรารีแต่ละรายการ ให้ค้นหาเอาต์พุต show
สำหรับ unique_id แต่ละรายการเพื่อหาชื่อฟังก์ชันที่ไม่ซ้ำกันสำหรับไลบรารีนั้นๆ
กรณีศึกษา: PGO สําหรับ ART
กรณีศึกษานี้แสดง ART เป็นตัวอย่างที่เข้าใจง่าย แต่ไม่ใช่คำอธิบายที่ถูกต้องของชุดไลบรารีจริงที่จัดทำโปรไฟล์สำหรับ ART หรือความสัมพันธ์ระหว่างไลบรารีเหล่านั้น
dex2oat
คอมไพเลอร์ล่วงหน้าใน ART ขึ้นอยู่กับ
libart-compiler.so
ซึ่งขึ้นอยู่กับ
libart.so
รันไทม์ ART ใช้งานได้ใน libart.so
เป็นหลัก การเปรียบเทียบประสิทธิภาพสำหรับคอมไพเลอร์และรันไทม์จะแตกต่างกันดังนี้
Benchmark | ไลบรารีที่โปรไฟล์ |
---|---|
dex2oat
|
dex2oat (ไฟล์ปฏิบัติการ), libart-compiler.so ,
libart.so |
art_runtime
|
libart.so
|
- เพิ่มพร็อพเพอร์ตี้
pgo
ต่อไปนี้ลงในdex2oat
libart-compiler.so
pgo: { instrumentation: true, benchmarks: ["dex2oat",], profile_file: "dex2oat.profdata", }
- เพิ่มพร็อพเพอร์ตี้
pgo
ต่อไปนี้ลงในlibart.so
pgo: { instrumentation: true, benchmarks: ["art_runtime", "dex2oat",], profile_file: "libart.profdata", }
- สร้างบิลด์ที่มีเครื่องมือวัดสำหรับข้อมูลเปรียบเทียบ
dex2oat
และart_runtime
โดยใช้สิ่งต่อไปนี้make ANDROID_PGO_INSTRUMENT=dex2oat make ANDROID_PGO_INSTRUMENT=art_runtime
- เรียกใช้การเปรียบเทียบการออกกำลังกาย
dex2oat
และart_runtime
เพื่อรับสิ่งต่อไปนี้- ไฟล์
.profraw
3 ไฟล์จากdex2oat
(dex2oat_exe.profdata
,dex2oat_libart-compiler.profdata
และdexeoat_libart.profdata
) ซึ่งระบุโดยใช้วิธีการที่อธิบายไว้ในการจัดการไฟล์โปรไฟล์ LLVM art_runtime_libart.profdata
รายการเดียว
- ไฟล์
- สร้างไฟล์ profdata ทั่วไปสำหรับ
dex2oat
ไฟล์ที่ปฏิบัติการได้และlibart-compiler.so
โดยใช้llvm-profdata merge -output=dex2oat.profdata \ dex2oat_exe.profdata dex2oat_libart-compiler.profdata
- รับโปรไฟล์ของ
libart.so
โดยการผสานโปรไฟล์จากข้อมูลเปรียบเทียบ 2 รายการต่อไปนี้llvm-profdata merge -output=libart.profdata \ dex2oat_libart.profdata art_runtime_libart.profdata
จํานวนดิบของ
libart.so
จาก 2 โปรไฟล์อาจแตกต่างกันเนื่องจากเบนช์มาร์กมีจํานวนกรณีทดสอบและระยะเวลาที่ทํางานแตกต่างกัน ในกรณีนี้ คุณสามารถใช้การผสานแบบถ่วงน้ำหนักได้llvm-profdata merge -output=libart.profdata \ -weighted-input=2,dex2oat_libart.profdata \ -weighted-input=1,art_runtime_libart.profdata
คําสั่งข้างต้นกําหนดน้ำหนักให้กับโปรไฟล์จาก
dex2oat
เป็น 2 เท่า น้ำหนักจริงควรกำหนดตามความรู้หรือการทดลองในโดเมน - ตรวจสอบไฟล์โปรไฟล์
dex2oat.profdata
และlibart.profdata
ไปยังtoolchain/pgo-profiles
เพื่อใช้ในระหว่างการสร้าง
หรือสร้างบิลด์ที่มีเครื่องมือวัดผลรายการเดียวซึ่งมีคลังทั้งหมดที่มีเครื่องมือวัดผลโดยใช้
make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime (or) make ANDROID_PGO_INSTRUMENT=ALL
คำสั่งที่ 2 จะสร้างโมดูลที่เปิดใช้ PGO ทั้งหมดสําหรับการสร้างโปรไฟล์