অর্ডার ফাইল একটি সাম্প্রতিক লিঙ্কার অপ্টিমাইজেশান কৌশল. এই অর্ডার ফাইলগুলি ফাংশন প্রতিনিধিত্বকারী প্রতীক ধারণকারী পাঠ্য ফাইল। lld এর মতো লিঙ্কাররা একটি নির্দিষ্ট ক্রমে লেআউট ফাংশন করার জন্য অর্ডার ফাইল ব্যবহার করে। এই বাইনারি বা লাইব্রেরিগুলি অর্ডারযুক্ত প্রতীকগুলির সাথে পৃষ্ঠার ত্রুটিগুলি হ্রাস করে এবং একটি প্রোগ্রামের কোল্ড-স্টার্টের সময় প্রতীকগুলির দক্ষ লোডিংয়ের কারণে একটি প্রোগ্রামের লঞ্চের সময় উন্নত করে।
অর্ডার ফাইল বৈশিষ্ট্য তিনটি ধাপ অনুসরণ করে আপনার অ্যাপ্লিকেশনে যোগ করা যেতে পারে:
- প্রোফাইল এবং ম্যাপিং ফাইল তৈরি করুন
- প্রোফাইল এবং ম্যাপিং ফাইল থেকে একটি অর্ডার ফাইল তৈরি করুন
- প্রতীক লেআউট করতে রিলিজ বিল্ডের সময় অর্ডার ফাইলটি ব্যবহার করুন
অর্ডার ফাইল তৈরি করুন
একটি অর্ডার ফাইল তৈরি করতে তিনটি ধাপ প্রয়োজন:
- অ্যাপটির একটি যন্ত্রযুক্ত সংস্করণ তৈরি করুন যা অর্ডার ফাইলটি লিখে
- প্রোফাইল তৈরি করতে অ্যাপটি চালান
- প্রোফাইল এবং ম্যাপিং ফাইল পোস্ট-প্রসেস
একটি ইন্সট্রুমেন্টেড বিল্ড তৈরি করুন
অ্যাপ্লিকেশনটির একটি ইন্সট্রুমেন্টেড বিল্ড চালানোর মাধ্যমে প্রোফাইলগুলি তৈরি করা হয়। একটি ইন্সট্রুমেন্টেড বিল্ডের জন্য কম্পাইলার এবং লিঙ্কার উভয় ফ্ল্যাগে -forder-file-instrumentation
যোগ করা প্রয়োজন -mllvm -orderfile-write-mapping=<filename>-mapping.txt
কম্পাইলার ফ্ল্যাগে কঠোরভাবে যুক্ত করা হচ্ছে। ইনস্ট্রুমেন্টেশন পতাকা প্রোফাইলিংয়ের জন্য অর্ডার ফাইল ইনস্ট্রুমেন্টেশন সক্ষম করে এবং প্রোফাইলিংয়ের জন্য প্রয়োজনীয় নির্দিষ্ট লাইব্রেরি লোড করে। অন্যদিকে, ম্যাপিং ফ্ল্যাগ শুধুমাত্র ম্যাপিং ফাইলটি আউটপুট করে যা বাইনারি বা লাইব্রেরির মধ্যে প্রতিটি ফাংশনের জন্য MD5 হ্যাশ দেখায়।
উপরন্তু, যে কোনো অপ্টিমাইজেশান ফ্ল্যাগ পাস করা নিশ্চিত করুন কিন্তু -O0
কারণ ইন্সট্রুমেন্টেশন ফ্ল্যাগ এবং ম্যাপিং পতাকা উভয়েরই একটি প্রয়োজন। কোনো অপ্টিমাইজেশান ফ্ল্যাগ পাস না হলে, ম্যাপিং ফাইল তৈরি হয় না এবং ইনস্ট্রুমেন্টেড বিল্ড প্রোফাইল ফাইলে ভুল হ্যাশ আউটপুট করতে পারে।
ndk-বিল্ড
APP_OPTIM=release
দিয়ে বিল্ড করতে ভুলবেন না যাতে ndk-build -O0
ছাড়া অন্য একটি অপ্টিমাইজেশান মোড ব্যবহার করে। এজিপি দিয়ে তৈরি করার সময় এটি রিলিজ বিল্ডের জন্য স্বয়ংক্রিয়।
LOCAL_CFLAGS += \
-forder-file-instrumentation \
-mllvm -orderfile-write-mapping=mapping.txt \
LOCAL_LDFLAGS += -forder-file-instrumentation
সিমেক
Debug
ছাড়া অন্য একটি CMAKE_BUILD_TYPE
ব্যবহার করতে ভুলবেন না যাতে CMake -O0
ছাড়া অন্য একটি অপ্টিমাইজেশান মোড ব্যবহার করে। এজিপি দিয়ে তৈরি করার সময় এটি রিলিজ বিল্ডের জন্য স্বয়ংক্রিয়।
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 .
আগেই উল্লেখ করা হয়েছে, লিখিত প্রোফাইল ফাইল ধারণকারী ফোল্ডারটি আপনার দ্বারা অ্যাক্সেস করা যেতে পারে তা নিশ্চিত করুন। এটি একটি ভার্চুয়াল ডিভাইস হলে, অনেক ফোল্ডারে অ্যাক্সেস না থাকার কারণে আপনি প্লে স্টোরের এমুলেটরগুলি এড়াতে চাইতে পারেন।
প্রোফাইল এবং ম্যাপিং ফাইল পোস্টপ্রসেস করুন
আপনি যখন প্রোফাইলগুলি পান, আপনাকে ম্যাপিং ফাইলটি খুঁজে বের করতে হবে এবং প্রতিটি প্রোফাইলকে একটি হেক্সাডেসিমাল বিন্যাসে রূপান্তর করতে হবে। সাধারণত, আপনি অ্যাপের বিল্ড ফোল্ডারে ম্যাপিং ফাইলটি খুঁজে পেতে পারেন। যখন আপনার কাছে উভয়ই থাকে, আপনি একটি প্রোফাইল ফাইল নিতে এবং অর্ডার ফাইল তৈরি করতে সঠিক ম্যাপিং ফাইল নিতে আমাদের স্ক্রিপ্ট ব্যবহার করতে পারেন৷
লিনাক্স/ম্যাক/ক্রোমওএস
hexdump -C default-%m.profraw.order > default-%m.prof
python3 create_orderfile.py --profile-file default-%m.prof --mapping-file <filename>-mapping.txt
উইন্ডোজ
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
পাস করতে হবে। কখনও কখনও, চিহ্নগুলি খুঁজে পাওয়া যায় না বা সরানো যায় না এবং সতর্কতাগুলি দিতে পারে না যাতে আপনি এই সতর্কতাগুলিকে দমন করতে -Wl,--no-warn-symbol-ordering
পাস করতে পারেন৷
ndk-বিল্ড
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 \
সিমেক
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 এর পদ্ধতি ব্যবহার করে তাই এটি আসল Java বা Kotlin অ্যাপের উপর আপনার C বা C++ শেয়ার করা লাইব্রেরির জন্য সবচেয়ে উপযোগী। ক্ল্যাং প্রতিটি ফাংশনের নাম (প্রতীক) নেয় এবং এটির একটি MD5 হ্যাশ তৈরি করে এবং একটি ম্যাপিং ফাইলের সাথে এই সম্পর্কটিকে আউটপুট করে। একটি ফাংশনের MD5 হ্যাশ প্রোফাইল ফাইলে (প্রোফ্রো ফরম্যাট) লেখা হয় যখন ফাংশনটি প্রথমবার কার্যকর হয়। ফাংশনের পরবর্তী কোনো এক্সিকিউশন প্রোফাইল ফাইলে এর MD5 হ্যাশ লিখবে না কারণ এটি ডুপ্লিকেট এড়াতে চায়। ফলস্বরূপ, ফাংশনের শুধুমাত্র প্রথম সঞ্চালন ক্রমানুসারে রেকর্ড করা হয়। প্রোফাইল ফাইল এবং ম্যাপিং ফাইলের মধ্য দিয়ে গিয়ে, আপনি প্রতিটি MD5 হ্যাশ নিতে পারেন এবং সংশ্লিষ্ট ফাংশনের সাথে এটি প্রতিস্থাপন করতে পারেন এবং একটি অর্ডার ফাইল পেতে পারেন।
হেক্সাডেসিমেল বিন্যাসে একটি প্রোফাইল ফাইল এবং একটি ম্যাপিং ফাইল উভয়ের উদাহরণ যথাক্রমে example.prof এবং example-mapping.txt হিসাবে পাওয়া যেতে পারে।