การเพิ่มประสิทธิภาพตามโปรไฟล์ (PGO) เป็นการเพิ่มประสิทธิภาพคอมไพเลอร์ซึ่งเป็นที่รู้จักกันดี ใน PGO โปรไฟล์รันไทม์จากการดำเนินการของโปรแกรมจะใช้โดย คอมไพเลอร์เพื่อตัดสินใจเลือกสิ่งที่เหมาะสมที่สุดเกี่ยวกับการแทรกในบรรทัดและการจัดวางโค้ด ซึ่งนำไปสู่ ประสิทธิภาพที่ดีขึ้นและลดขนาดโค้ดลง
คุณสามารถทำให้ PGO ใช้งานได้ในแอปพลิเคชันหรือไลบรารีของคุณโดยทำตามขั้นตอนต่อไปนี้ 1. ระบุภาระงานตัวแทน 2. รวบรวมโปรไฟล์ 3. ใช้โปรไฟล์ในรุ่นที่เผยแพร่
ขั้นตอนที่ 1: ระบุภาระงานตัวแทน
ก่อนอื่นให้ระบุการเปรียบเทียบที่เป็นตัวแทนหรือภาระงานสำหรับแอปพลิเคชันของคุณ ซึ่งเป็นขั้นตอนสำคัญเนื่องจากโปรไฟล์ที่รวบรวมจากภาระงานจะระบุ ร้อนและเย็นในโค้ด เมื่อใช้โปรไฟล์ คอมไพเลอร์จะ ทำการเพิ่มประสิทธิภาพอย่างเข้มงวดและแทรกอยู่ในพื้นที่ที่มีอากาศร้อน ผู้คอมไพเลอร์ อาจเลือกที่จะลดขนาดรหัสของพื้นที่หนาวเย็น ด้านประสิทธิภาพ
การระบุปริมาณงานที่ดียังช่วยให้ติดตามประสิทธิภาพใน ทั่วไป
ขั้นตอนที่ 2: รวบรวมโปรไฟล์
การเก็บรวบรวมโปรไฟล์มี 3 ขั้นตอนดังนี้ - การสร้างโค้ดแบบเนทีฟพร้อมการวัดคุม - การเรียกใช้แอปที่มีการวัดบนอุปกรณ์และสร้างโปรไฟล์ และ - การรวม/หลังการประมวลผลโปรไฟล์ในโฮสต์
สร้างบิลด์ที่มีเครื่องดนตรี
โปรไฟล์จะรวบรวมโดยการเรียกใช้ภาระงานจากขั้นตอนที่ 1 ใน
บิลด์ที่มีการวัดคุมของแอปพลิเคชัน หากต้องการสร้างบิลด์ที่มีการวัดคุม ให้เพิ่ม
-fprofile-generate
ไปยังแฟล็กของคอมไพเลอร์และ Linker การตั้งค่าสถานะนี้ควรเป็น
ควบคุมโดยตัวแปรบิลด์ที่แยกต่างหาก เนื่องจากไม่จำเป็นต้องมี Flag ในระหว่าง
บิลด์เริ่มต้น
สร้างโปรไฟล์
จากนั้นเรียกใช้แอปที่มีการวัดในอุปกรณ์แล้วสร้างโปรไฟล์
ระบบจะรวบรวมโปรไฟล์ในหน่วยความจำเมื่อเรียกใช้ไบนารีที่มีการวัดและรับ
เขียนลงในไฟล์เมื่อออก แต่ฟังก์ชันที่ลงทะเบียนด้วย atexit
จะไม่
ที่มีการเรียกใช้ในแอป Android แอปจะหยุดทำงาน
แอปพลิเคชัน/ภาระงานต้องทำงานเพิ่มเติมเพื่อกำหนดเส้นทางให้กับไฟล์โปรไฟล์ จากนั้นจึงทริกเกอร์การเขียนโปรไฟล์อย่างชัดเจน
- หากต้องการกำหนดเส้นทางไฟล์โปรไฟล์ ให้โทร
__llvm_profile_set_filename(PROFILE_DIR "/default-%m.profraw
%m
มีประโยชน์ เมื่อมีไลบรารีที่ใช้ร่วมกันหลายรายการ %m` ขยายเป็นโมดูลที่ไม่ซ้ำกัน สำหรับไลบรารีดังกล่าว ซึ่งทำให้มีโปรไฟล์แยกต่างหากต่อไลบรารี โปรดดู ที่นี่ สำหรับตัวระบุรูปแบบที่มีประโยชน์อื่นๆ PROFILE_DIR เป็นไดเรกทอรีที่ เขียนได้จากแอป ดูการสาธิต สำหรับการตรวจหาไดเรกทอรีนี้ขณะรันไทม์ - หากต้องการเรียกใช้การเขียนโปรไฟล์อย่างชัดเจน ให้เรียกใช้
__llvm_profile_write_file
extern "C" {
extern int __llvm_profile_set_filename(const char*);
extern int __llvm_profile_write_file(void);
}
#define PROFILE_DIR "<location-writable-from-app>"
void workload() {
// ...
// run workload
// ...
// set path and write profiles after workload execution
__llvm_profile_set_filename(PROFILE_DIR "/default-%m.profraw");
__llvm_profile_write_file();
return;
}
หมายเหตุ: การสร้างไฟล์โปรไฟล์จะง่ายขึ้นหากภาระงานเป็นไบนารีแบบสแตนด์อโลน
เพียงตั้งค่าตัวแปรสภาพแวดล้อม LLVM_PROFILE_FILE
เป็น %t/default-%m.profraw
ก่อนเรียกใช้ไบนารี
โปรไฟล์หลังกระบวนการ
ไฟล์โปรไฟล์อยู่ในรูปแบบ .profraw โดยจะต้องดึงข้อมูลจาก
อุปกรณ์ที่ใช้ adb pull
หลังจากดึงข้อมูลแล้ว ให้ใช้ยูทิลิตี llvm-profdata
ใน
NDK เพื่อแปลงจาก .profraw
เป็น .profdata
ซึ่งส่งผ่านไปยัง
คอมไพเลอร์
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-profdata \
merge --output=pgo_profile.profdata \
<list-of-profraw-files>
ใช้ llvm-profdata
และ clang
จาก NDK รุ่นเดียวกันเพื่อหลีกเลี่ยงเวอร์ชัน
รูปแบบไฟล์โปรไฟล์ไม่ตรงกัน
ขั้นตอนที่ 3 ใช้โปรไฟล์เพื่อสร้างแอปพลิเคชัน
ใช้โปรไฟล์จากขั้นตอนก่อนหน้าระหว่างบิลด์รุ่นของ
ผ่านการส่ง -fprofile-use=<>.profdata
ไปยังคอมไพเลอร์และ Linker
ยังสามารถใช้โปรไฟล์ได้แม้ในขณะที่โค้ดพัฒนาขึ้น โดยคอมไพเลอร์ Clang สามารถทนต่อ
แหล่งที่มาและโปรไฟล์ไม่ตรงกันเล็กน้อย
หมายเหตุ: โดยทั่วไปแล้ว โปรไฟล์สำหรับไลบรารีส่วนใหญ่จะใช้กันตามสถาปัตยกรรม เช่น โปรไฟล์ที่สร้างจากบิลด์ arm64 ของไลบรารีสามารถใช้เพื่อ สถาปัตยกรรมทั้งหมด ข้อควรระวังก็คือหากมีงานด้านสถาปัตยกรรม เส้นทางโค้ดในไลบรารี (Arm กับ x86 หรือ 32 บิตกับ 64 บิต) โปรไฟล์แยกต่างหาก ควรใช้สำหรับการกำหนดค่าดังกล่าวแต่ละรายการ
สรุปข้อมูลทั้งหมด
https://github.com/DanAlbert/ndk-ตัวอย่าง/tree/pgo/pgo แสดงการสาธิตการใช้ PGO จากแอปตั้งแต่ต้นจนจบ จะให้รางวัลเพิ่มเติม รายละเอียดคร่าวๆ ในเอกสารฉบับนี้
- บิลด์ CMake กฎ แสดงวิธีการตั้งค่าตัวแปร CMake ที่สร้างโค้ดแบบเนทีฟพร้อมการวัดคุม เมื่อไม่ได้ตั้งค่าตัวแปรบิลด์ โค้ดเนทีฟจะได้รับการเพิ่มประสิทธิภาพโดยใช้ สร้างโปรไฟล์ PGO แล้ว
- ในบิลด์ที่มีเครื่องดนตรี pgodemo.cpp เขียนว่าโปรไฟล์เป็นการดำเนินการสำหรับภาระงาน
- จะได้รับตำแหน่งที่เขียนได้สำหรับโปรไฟล์ขณะรันไทม์ใน
MainActivity.kt
โดยใช้
applicationContext.cacheDir.toString()
- หากต้องการดึงโปรไฟล์จากอุปกรณ์โดยไม่ต้องใช้
adb root
ให้ใช้adb
สูตรอาหาร ที่นี่