สั่งซื้อไฟล์

ไฟล์คำสั่งซื้อเป็นเทคนิคการเพิ่มประสิทธิภาพ Linker ล่าสุด ไฟล์คำสั่งซื้อเหล่านี้เป็นไฟล์ข้อความที่มีสัญลักษณ์ที่แสดงถึงฟังก์ชัน Linker เช่น lld ใช้ไฟล์คำสั่งซื้อเพื่อจัดวางฟังก์ชันตามลำดับที่เฉพาะเจาะจง ไบนารีหรือไลบรารีเหล่านี้ที่มีสัญลักษณ์ที่จัดเรียงแล้วจะช่วยลดข้อผิดพลาดของเพจและปรับปรุงเวลาเปิดตัวโปรแกรมเนื่องจากการโหลดสัญลักษณ์อย่างมีประสิทธิภาพระหว่างการเริ่มต้นแบบเย็นของโปรแกรม

คุณสามารถเพิ่มฟีเจอร์ไฟล์คำสั่งซื้อลงในแอปพลิเคชันได้โดยทำตาม 3 ขั้นตอนต่อไปนี้

  1. สร้างโปรไฟล์และไฟล์การจับคู่
  2. สร้างไฟล์คำสั่งซื้อจากโปรไฟล์และไฟล์การจับคู่
  3. ใช้ไฟล์คำสั่งซื้อระหว่างบิลด์ที่เผยแพร่เพื่อจัดวางสัญลักษณ์

สร้างไฟล์คำสั่งซื้อ

การสร้างไฟล์คำสั่งซื้อต้องทำ 3 ขั้นตอนต่อไปนี้

  1. สร้างแอปเวอร์ชันที่ติดตั้งเครื่องมือเพื่อเขียนไฟล์คำสั่งซื้อ
  2. เรียกใช้แอปเพื่อสร้างโปรไฟล์
  3. ประมวลผลโปรไฟล์และไฟล์การจับคู่หลังการประมวลผล

สร้างบิลด์ที่ติดตั้งเครื่องมือ

ระบบจะสร้างโปรไฟล์โดยการเรียกใช้บิลด์ที่ติดตั้งเครื่องมือของแอปพลิเคชัน บิลด์ที่ติดตั้งเครื่องมือต้องเพิ่ม -forder-file-instrumentation ลงใน แฟล็กคอมไพเลอร์และ Linker พร้อมกับ -mllvm -orderfile-write-mapping=<filename>-mapping.txt เพิ่มลงในแฟล็กคอมไพเลอร์อย่างเคร่งครัด แฟล็กการวัดคุมจะเปิดใช้การวัดคุมไฟล์คำสั่งซื้อสำหรับการสร้างโปรไฟล์และโหลดไลบรารีที่เฉพาะเจาะจงซึ่งจำเป็นสำหรับการสร้างโปรไฟล์ ในทางกลับกัน แฟล็กการจับคู่จะแสดงไฟล์การจับคู่ที่แสดงแฮช MD5 สำหรับแต่ละฟังก์ชันภายในไบนารีหรือไลบรารี

นอกจากนี้ โปรดส่งแฟล็กการเพิ่มประสิทธิภาพใดๆ ยกเว้น -O0 เนื่องจากทั้งแฟล็กการวัดคุมและแฟล็กการจับคู่ต้องใช้แฟล็กการเพิ่มประสิทธิภาพ หากไม่มีการส่งแฟล็กการเพิ่มประสิทธิภาพ ระบบจะไม่สร้างไฟล์การจับคู่และบิลด์ที่ติดตั้งเครื่องมืออาจแสดงแฮชที่ไม่ถูกต้องไปยังไฟล์โปรไฟล์

ndk-build

ตรวจสอบว่าได้สร้างด้วย APP_OPTIM=release เพื่อให้ ndk-build ใช้โหมดการเพิ่มประสิทธิภาพอื่นที่ไม่ใช่ -O0 เมื่อสร้างด้วย AGP การดำเนินการนี้จะเกิดขึ้นโดยอัตโนมัติสำหรับบิลด์รุ่นที่ใช้งานจริง

LOCAL_CFLAGS += \
    -forder-file-instrumentation \
    -mllvm -orderfile-write-mapping=mapping.txt \

LOCAL_LDFLAGS += -forder-file-instrumentation

CMake

ตรวจสอบว่าได้ใช้ CMAKE_BUILD_TYPE อื่นที่ไม่ใช่ Debug เพื่อให้ CMake ใช้โหมดการเพิ่มประสิทธิภาพอื่นที่ไม่ใช่ -O0 เมื่อสร้างด้วย AGP การดำเนินการนี้จะเกิดขึ้นโดยอัตโนมัติสำหรับบิลด์รุ่นที่ใช้งานจริง

target_compile_options(orderfiledemo PRIVATE
    -forder-file-instrumentation
    -mllvm -orderfile-write-mapping=mapping.txt
)
target_link_options(orderfiledemo PRIVATE -forder-file-instrumentation)

ระบบบิลด์อื่นๆ

คอมไพล์โค้ดโดยใช้ -forder-file-instrumentation -O1 -mllvm -orderfile-write-mapping=mapping.txt

ไม่จำเป็นต้องใช้ -O1 โดยเฉพาะ แต่ห้ามใช้ -O0

ละเว้น -mllvm -orderfile-write-mapping=mapping.txt เมื่อลิงก์

บิลด์ที่เผยแพร่ไม่จำเป็นต้องใช้แฟล็กเหล่านี้ทั้งหมด ดังนั้นจึงควรควบคุมโดยตัวแปรบิลด์ คุณสามารถตั้งค่าทั้งหมดนี้ใน CMakeLists.txt ได้อย่างง่ายดาย เช่น ในตัวอย่าง ของเรา

สร้างไลบรารีไฟล์คำสั่งซื้อ

นอกเหนือจากแฟล็กแล้ว คุณต้องตั้งค่าไฟล์โปรไฟล์และไบนารีที่ติดตั้งเครื่องมือต้องทริกเกอร์การเขียนโปรไฟล์อย่างชัดเจนระหว่างการดำเนินการ

  • เรียกใช้ __llvm_profile_set_filename(PROFILE_DIR "/<filename>-%m.profraw") เพื่อ ตั้งค่าเส้นทางโปรไฟล์ แม้ว่าอาร์กิวเมนต์ที่ส่งจะเป็น <filename>-%m.profraw แต่ระบบจะบันทึกไฟล์โปรไฟล์เป็น <filename>-%m.profraw.order ตรวจสอบว่าแอปเขียน PROFILE_DIR ได้และคุณมีสิทธิ์เข้าถึงไดเรกทอรี
    • %m มีประโยชน์เนื่องจากขยายเป็นลายเซ็นโมดูลที่ไม่ซ้ำกันสำหรับไลบรารี ซึ่งส่งผลให้มีโปรไฟล์แยกกันสำหรับแต่ละไลบรารี เนื่องจากมีการสร้างโปรไฟล์ไลบรารีที่แชร์จำนวนมาก ดูตัวระบุรูปแบบเพิ่มเติมได้จาก ลิงก์นี้
  • เรียกใช้ __llvm_profile_initialize_file() เพื่อตั้งค่าไฟล์โปรไฟล์
  • เรียกใช้ __llvm_orderfile_dump() เพื่อเขียนลงในไฟล์โปรไฟล์อย่างชัดเจน

ระบบจะรวบรวมโปรไฟล์ไว้ในหน่วยความจำและฟังก์ชันการดัมพ์จะเขียนโปรไฟล์ลงในไฟล์ คุณต้องตรวจสอบว่าได้เรียกใช้ฟังก์ชันการดัมพ์เมื่อสิ้นสุดการเริ่มต้น เพื่อให้ไฟล์โปรไฟล์มีสัญลักษณ์ทั้งหมดจนถึงสิ้นสุดการเริ่มต้น

extern "C" {
extern int __llvm_profile_set_filename(const char*);
extern int __llvm_profile_initialize_file(void);
extern int __llvm_orderfile_dump(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_initialize_file();
  __llvm_orderfile_dump();
  return;
}

เรียกใช้บิลด์สำหรับโปรไฟล์

เรียกใช้แอปที่ติดตั้งเครื่องมือในอุปกรณ์จริงหรืออุปกรณ์เสมือนจริงเพื่อสร้างโปรไฟล์ คุณสามารถแยกไฟล์โปรไฟล์ได้โดยใช้ adb pull

adb shell "run-as <package-name> sh -c 'cat /data/user/0/<package-name>/cache/default-%m.profraw.order' | cat > /data/local/tmp/default-%m.profraw.order"
adb pull /data/local/tmp/default-%m.profraw.order .

โปรดตรวจสอบว่าคุณมีสิทธิ์เข้าถึงโฟลเดอร์ที่มีไฟล์โปรไฟล์ที่เขียนไว้ หากเป็นอุปกรณ์เสมือนจริง คุณอาจต้องการหลีกเลี่ยงโปรแกรมจำลองที่มี Play Store เนื่องจากไม่มีสิทธิ์เข้าถึงโฟลเดอร์จำนวนมาก

ประมวลผลโปรไฟล์และไฟล์การจับคู่หลังการประมวลผล

เมื่อได้รับโปรไฟล์แล้ว คุณต้องค้นหาไฟล์การจับคู่และแปลงแต่ละโปรไฟล์เป็นรูปแบบเลขฐาน 16 โดยปกติแล้ว คุณจะพบไฟล์การจับคู่ในโฟลเดอร์บิลด์ของแอป เมื่อมีทั้ง 2 ไฟล์แล้ว คุณสามารถใช้สคริปต์ ของเราเพื่อใช้ไฟล์โปรไฟล์และไฟล์การจับคู่ที่ถูกต้องเพื่อสร้างไฟล์คำสั่งซื้อ

Linux/Mac/ChromeOS

hexdump -C default-%m.profraw.order > default-%m.prof
python3 create_orderfile.py --profile-file default-%m.prof --mapping-file <filename>-mapping.txt

Windows

certutil -f -encodeHex default-%m.profraw.order default-%m.prof
python3 create_orderfile.py --profile-file default-%m.prof --mapping-file <filename>-mapping.txt

หากต้องการอ่านเพิ่มเติมเกี่ยวกับสคริปต์ โปรดดู README นี้

ใช้ไฟล์คำสั่งซื้อเพื่อสร้างแอปพลิเคชัน

หลังจากสร้างไฟล์คำสั่งซื้อแล้ว คุณควรนำแฟล็กก่อนหน้าและฟังก์ชันไฟล์คำสั่งซื้อออก เนื่องจากแฟล็กและฟังก์ชันเหล่านั้นมีไว้สำหรับขั้นตอนการสร้างเท่านั้น คุณเพียงต้องส่ง -Wl,--symbol-ordering-file=<filename>.orderfile ไปยัง แฟล็กคอมไพล์และ Linker บางครั้งระบบอาจไม่พบหรือย้ายสัญลักษณ์ไม่ได้และแสดงคำเตือน ดังนั้นคุณจึงส่ง -Wl,--no-warn-symbol-ordering เพื่อระงับคำเตือนเหล่านี้ได้

ndk-build

LOCAL_CFLAGS += \
    -Wl,--symbol-ordering-file=<filename>.orderfile \
    -Wl,--no-warn-symbol-ordering \

LOCAL_LDFLAGS += \
    -Wl,--symbol-ordering-file=<filename>.orderfile \
    -Wl,--no-warn-symbol-ordering \

CMake

target_compile_options(orderfiledemo PRIVATE
    -Wl,--symbol-ordering-file=<filename>.orderfile
    -Wl,--no-warn-symbol-ordering
)
target_link_options(orderfiledemo PRIVATE
    -Wl,--symbol-ordering-file=<filename>.orderfile
    -Wl,--no-warn-symbol-ordering
)

ระบบบิลด์อื่นๆ

คอมไพล์โค้ดโดยใช้ -Wl,--symbol-ordering-file=<filename>.orderfile -Wl,--no-warn-symbol-ordering

ดูข้อมูลเพิ่มเติมได้ที่ตัวอย่างไฟล์คำสั่งซื้อ

รายละเอียดการติดตั้งใช้งานไฟล์คำสั่งซื้อ

คุณสร้างไฟล์คำสั่งซื้อและใช้ไฟล์ดังกล่าวเพื่อสร้างได้หลายวิธี NDK ใช้เมธอดของ LLVM จึงมีประโยชน์มากที่สุดสำหรับไลบรารีที่แชร์ C หรือ C++ มากกว่าแอป Java หรือ Kotlin จริง Clang จะใช้ชื่อฟังก์ชัน (สัญลักษณ์) ทุกชื่อและสร้างแฮช MD5 ของชื่อฟังก์ชันนั้นๆ แล้วแสดงความสัมพันธ์นี้ไปยังไฟล์การจับคู่ ระบบจะเขียนแฮช MD5 ของฟังก์ชันลงในไฟล์โปรไฟล์ (รูปแบบ profraw) เมื่อฟังก์ชันทำงานเป็นครั้งแรก การทำงานของฟังก์ชันในครั้งต่อๆ ไปจะไม่เขียนแฮช MD5 ลงในไฟล์โปรไฟล์ เนื่องจากระบบต้องการหลีกเลี่ยงรายการที่ซ้ำกัน ด้วยเหตุนี้ ระบบจึงบันทึกเฉพาะการทำงานครั้งแรกของฟังก์ชันตามลำดับ เมื่อดูไฟล์โปรไฟล์และไฟล์การจับคู่ คุณจะใช้แฮช MD5 แต่ละรายการและแทนที่ด้วยฟังก์ชันที่เกี่ยวข้องเพื่อรับไฟล์คำสั่งซื้อได้

ตัวอย่างทั้งไฟล์โปรไฟล์ในรูปแบบเลขฐาน 16 และไฟล์การจับคู่จะสามารถ พบได้ในรูปแบบ example.prof และ example-mapping.txt ตามลำดับ