Android 8.0 ART এর উন্নতি

অ্যান্ড্রয়েড ৮.০ সংস্করণে অ্যান্ড্রয়েড রানটাইম (ART)-কে উল্লেখযোগ্যভাবে উন্নত করা হয়েছে। ডিভাইস নির্মাতারা ART-তে যে উন্নতিগুলো আশা করতে পারেন, তার একটি সংক্ষিপ্ত তালিকা নিচে দেওয়া হলো।

একযোগে কম্প্যাক্টিং গার্বেজ কালেক্টর

গুগল আই/ও-তে ঘোষিত ঘোষণা অনুযায়ী, অ্যান্ড্রয়েড ৮.০-তে ART একটি নতুন কনকারেন্ট কম্প্যাক্টিং গার্বেজ কালেক্টর (GC) নিয়ে এসেছে। এই কালেক্টরটি প্রতিবার GC চলার সময় এবং অ্যাপ চলার সময় হিপকে কম্প্যাক্ট করে, শুধুমাত্র থ্রেড রুট প্রসেস করার জন্য একবার অল্প সময়ের জন্য বিরতি নেয়। এর সুবিধাগুলো হলো:

  • GC সর্বদা হিপকে কম্প্যাক্ট করে: অ্যান্ড্রয়েড ৭.০-এর তুলনায় গড়ে ৩২% ছোট হিপ সাইজ।
  • কম্প্যাকশন থ্রেড লোকাল বাম্প পয়েন্টার অবজেক্ট অ্যালোকেশন সক্ষম করে: অ্যালোকেশন অ্যান্ড্রয়েড ৭.০-এর তুলনায় ৭০% দ্রুততর।
  • অ্যান্ড্রয়েড ৭.০ জিসি-এর তুলনায় এইচ২ বেঞ্চমার্কের জন্য পজ টাইম ৮৫% কম।
  • হিপ সাইজের সাথে পজ টাইম আর বাড়বে না; অ্যাপগুলো এখন জ্যাঙ্ক নিয়ে চিন্তা না করেই বড় হিপ ব্যবহার করতে পারবে।
  • GC বাস্তবায়নের বিবরণ - বাধাগুলো পড়ুন:
    • রিড ব্যারিয়ার হলো প্রতিটি অবজেক্ট ফিল্ড রিড করার জন্য করা অল্প পরিমাণ কাজ।
    • এগুলো কম্পাইলারে অপ্টিমাইজ করা হয়েছে, কিন্তু কিছু ক্ষেত্রে ব্যবহারের গতি কমিয়ে দিতে পারে।

লুপ অপ্টিমাইজেশন

অ্যান্ড্রয়েড ৮.০ সংস্করণে ART বিভিন্ন ধরনের লুপ অপ্টিমাইজেশন প্রয়োগ করে থাকে:

  • সীমানা যাচাই নির্মূল
    • স্থির: কম্পাইল-টাইমে রেঞ্জগুলো সীমার মধ্যে আছে বলে প্রমাণিত হয়।
    • ডাইনামিক: রান-টাইম টেস্ট নিশ্চিত করে যে লুপগুলো সীমার মধ্যে থাকে (অন্যথায় বর্জন করা হয়)
  • আবেশন পরিবর্তনশীল নির্মূল
    • মৃত আবেশন অপসারণ করুন
    • লুপের পরে ব্যবহৃত আরোহ পদ্ধতিকে বদ্ধ-রূপ রাশিমালা দ্বারা প্রতিস্থাপন করুন।
  • লুপের বডির ভেতরে ডেড কোড এলিমিনেশন, অর্থাৎ অকার্যকর হয়ে যাওয়া পুরো লুপ অপসারণ করা।
  • শক্তি হ্রাস
  • লুপ রূপান্তর: বিপরীতকরণ, বিনিময়, বিভাজন, উন্মোচন, ইউনিমডুলার, ইত্যাদি।
  • SIMDization (ভেক্টরাইজেশন নামেও পরিচিত)

লুপ অপটিমাইজারটি ART কম্পাইলারে তার নিজস্ব অপটিমাইজেশন পাসে অবস্থান করে। বেশিরভাগ লুপ অপটিমাইজেশন অন্যান্য স্থানের অপটিমাইজেশন এবং সরলীকরণের মতোই হয়ে থাকে। কিছু অপটিমাইজেশনের ক্ষেত্রে সমস্যা দেখা দেয়, যেগুলো CFG-কে স্বাভাবিকের চেয়ে বেশি বিস্তৃতভাবে পুনর্লিখন করে, কারণ বেশিরভাগ CFG ইউটিলিটি (nodes.h দেখুন) একটি CFG তৈরি করার উপর মনোযোগ দেয়, পুনর্লিখনের উপর নয়।

শ্রেণী শ্রেণিবিন্যাস বিশ্লেষণ

অ্যান্ড্রয়েড ৮.০-এর ART, ক্লাস হায়ারার্কি অ্যানালাইসিস (CHA) ব্যবহার করে। এটি একটি কম্পাইলার অপটিমাইজেশন যা ক্লাস হায়ারার্কি বিশ্লেষণ করে প্রাপ্ত তথ্যের উপর ভিত্তি করে ভার্চুয়াল কলগুলোকে ডিভারচুয়ালাইজ করে ডাইরেক্ট কলে পরিণত করে। ভার্চুয়াল কলগুলো ব্যয়বহুল, কারণ এগুলো একটি vtable লুকআপের উপর ভিত্তি করে বাস্তবায়িত হয় এবং এর জন্য কয়েকটি ডিপেন্ডেন্ট লোডের প্রয়োজন হয়। এছাড়াও, ভার্চুয়াল কল ইনলাইন করা যায় না।

সম্পর্কিত উন্নয়নগুলোর সারসংক্ষেপ নিচে দেওয়া হলো:

  • ডাইনামিক সিঙ্গেল-ইমপ্লিমেন্টেশন মেথড স্ট্যাটাস আপডেটিং - ক্লাস লিঙ্কিং-এর শেষে, যখন vtable-টি ডেটা দ্বারা পূর্ণ হয়ে যায়, ART সুপার ক্লাসের vtable-এর সাথে প্রতিটি এন্ট্রির আলাদা আলাদা তুলনা করে।
  • কম্পাইলার অপ্টিমাইজেশন - কম্পাইলার একটি মেথডের সিঙ্গেল-ইমপ্লিমেন্টেশন তথ্যের সুবিধা নেবে। যদি A.foo মেথডটিতে সিঙ্গেল-ইমপ্লিমেন্টেশন ফ্ল্যাগ সেট করা থাকে, তাহলে কম্পাইলার ভার্চুয়াল কলটিকে একটি ডিভারচুয়ালাইজ করে ডিরেক্ট কলে পরিণত করবে এবং ফলস্বরূপ ডিরেক্ট কলটিকে ইনলাইন করার চেষ্টা করবে।
  • কম্পাইল করা কোড বাতিলকরণ - এছাড়াও ক্লাস লিঙ্কিংয়ের শেষে যখন একক-বাস্তবায়ন তথ্য আপডেট করা হয়, তখন যদি A.foo মেথডটির পূর্বে একক-বাস্তবায়ন অবস্থা থাকে কিন্তু সেই অবস্থাটি এখন বাতিল হয়ে যায়, তবে যে সমস্ত কম্পাইল করা কোড এই অনুমানের উপর নির্ভর করে যে মেথডটি একক-বাস্তবায়ন, সেগুলোরও কম্পাইল করা কোড বাতিল করতে হবে।
  • ডিঅপ্টিমাইজেশন - স্ট্যাকে থাকা লাইভ কম্পাইল করা কোডের সঠিকতা নিশ্চিত করার জন্য, বাতিল হয়ে যাওয়া কম্পাইল করা কোডটিকে ইন্টারপ্রেটার মোডে আনতে ডিঅপ্টিমাইজেশন শুরু করা হবে। ডিঅপ্টিমাইজেশনের একটি নতুন পদ্ধতি ব্যবহার করা হবে, যা সিনক্রোনাস এবং অ্যাসিনক্রোনাস ডিঅপ্টিমাইজেশনের একটি সংমিশ্রণ।

.oat ফাইলগুলিতে ইনলাইন ক্যাশে

ART এখন ইনলাইন ক্যাশে ব্যবহার করে এবং সেইসব কল সাইটকে অপ্টিমাইজ করে, যেগুলোর জন্য পর্যাপ্ত ডেটা বিদ্যমান। ইনলাইন ক্যাশে ফিচারটি প্রোফাইলে অতিরিক্ত রানটাইম তথ্য রেকর্ড করে এবং এহেড অফ টাইম কম্পাইলেশনে ডাইনামিক অপ্টিমাইজেশন যোগ করার জন্য তা ব্যবহার করে।

ডেক্সলেআউট

Dexlayout হলো Android 8.0-তে প্রবর্তিত একটি লাইব্রেরি, যা dex ফাইল বিশ্লেষণ করে এবং একটি প্রোফাইল অনুযায়ী সেগুলোকে পুনর্বিন্যাস করে। Dexlayout-এর লক্ষ্য হলো ডিভাইসে নিষ্ক্রিয় রক্ষণাবেক্ষণ কম্পাইলেশনের সময় রানটাইম প্রোফাইলিং তথ্য ব্যবহার করে dex ফাইলের বিভিন্ন অংশকে পুনর্বিন্যাস করা। dex ফাইলের যে অংশগুলো প্রায়শই একসাথে অ্যাক্সেস করা হয়, সেগুলোকে একত্রিত করার মাধ্যমে প্রোগ্রামগুলো উন্নত লোকালিটি থেকে আরও ভালো মেমরি অ্যাক্সেস প্যাটার্ন পেতে পারে, যা RAM সাশ্রয় করে এবং স্টার্ট-আপ সময় কমিয়ে আনে।

যেহেতু বর্তমানে প্রোফাইলের তথ্য শুধুমাত্র অ্যাপগুলো চালানোর পরেই পাওয়া যায়, তাই নিষ্ক্রিয় রক্ষণাবেক্ষণের সময় dex2oat-এর অন-ডিভাইস কম্পাইলেশনে dexlayout-কে একীভূত করা হয়।

ডেক্স ক্যাশে অপসারণ

অ্যান্ড্রয়েড ৭.০ পর্যন্ত, DexCache অবজেক্টটির চারটি বড় অ্যারে ছিল, যা DexFile-এর নির্দিষ্ট কিছু উপাদানের সংখ্যার সমানুপাতিক ছিল, যথা:

  • স্ট্রিং (প্রতিটি DexFile::StringId-এর জন্য একটি রেফারেন্স),
  • প্রকার (প্রতিটি DexFile::TypeId-এর জন্য একটি রেফারেন্স),
  • পদ্ধতিসমূহ (প্রতিটি DexFile::MethodId-এর জন্য একটি নেটিভ পয়েন্টার),
  • ফিল্ডসমূহ (প্রতিটি DexFile::FieldId-এর জন্য একটি নেটিভ পয়েন্টার)।

এই অ্যারেগুলো পূর্বে রিজলভ করা অবজেক্টগুলো দ্রুত খুঁজে বের করার জন্য ব্যবহৃত হতো। অ্যান্ড্রয়েড ৮.০-তে, মেথডস অ্যারে ছাড়া বাকি সব অ্যারে সরিয়ে ফেলা হয়েছে।

দোভাষীর পারফরম্যান্স

অ্যান্ড্রয়েড ৭.০ সংস্করণে 'mterp' চালু হওয়ার ফলে ইন্টারপ্রেটারের পারফরম্যান্স উল্লেখযোগ্যভাবে উন্নত হয়েছে। এটি এমন একটি ইন্টারপ্রেটার যার মূল ফেচ/ডিকোড/ইন্টারপ্রিট প্রক্রিয়াটি অ্যাসেম্বলি ভাষায় লেখা। Mterp দ্রুতগতির Dalvik ইন্টারপ্রেটারের আদলে তৈরি এবং এটি arm, arm64, x86, x86_64, mips ও mips64 সমর্থন করে। কম্পিউটেশনাল কোডের ক্ষেত্রে, Art-এর mterp মোটামুটি Dalvik-এর দ্রুতগতির ইন্টারপ্রেটারের সমতুল্য। তবে, কিছু ক্ষেত্রে এটি উল্লেখযোগ্যভাবে—এমনকি নাটকীয়ভাবেও—ধীর হতে পারে।

  1. কর্মক্ষমতা আহ্বান করুন।
  2. স্ট্রিং ম্যানিপুলেশন, এবং ডালভিকে ইনট্রিনসিক হিসেবে স্বীকৃত মেথডগুলোর অন্যান্য বহুল ব্যবহৃত কাজ।
  3. স্ট্যাক মেমরির ব্যবহার বৃদ্ধি পেয়েছে।

অ্যান্ড্রয়েড ৮.০ এই সমস্যাগুলোর সমাধান করে।

আরও ইনলাইনিং

অ্যান্ড্রয়েড ৬.০ থেকে, ART একই ডেক্স ফাইলের মধ্যে যেকোনো কল ইনলাইন করতে পারলেও, ভিন্ন ডেক্স ফাইলের শুধুমাত্র লিফ মেথডগুলোই ইনলাইন করতে পারত। এই সীমাবদ্ধতার দুটি কারণ ছিল:

  1. অন্য একটি ডেক্স ফাইল থেকে ইনলাইনিং করার জন্য সেই অন্য ডেক্স ফাইলটির ডেক্স ক্যাশে ব্যবহার করতে হয়, যা একই ডেক্স ফাইল থেকে ইনলাইনিং করার ক্ষেত্রে সম্ভব নয়, কারণ সেক্ষেত্রে কলার ফাইলের ডেক্স ক্যাশে পুনরায় ব্যবহার করা যেত। কম্পাইল করা কোডে স্ট্যাটিক কল, স্ট্রিং লোড বা ক্লাস লোডের মতো কয়েকটি নির্দেশনার জন্য ডেক্স ক্যাশে প্রয়োজন হয়।
  2. স্ট্যাক ম্যাপগুলো শুধুমাত্র বর্তমান ডেক্স ফাইলের মধ্যে একটি মেথড ইনডেক্সকে এনকোড করে।

এই সীমাবদ্ধতাগুলো দূর করতে অ্যান্ড্রয়েড ৮.০:

  1. কম্পাইল করা কোড থেকে ডেক্স ক্যাশে অ্যাক্সেস অপসারণ করে (আরও দেখুন "ডেক্স ক্যাশে অপসারণ" বিভাগটি)।
  2. স্ট্যাক ম্যাপ এনকোডিং প্রসারিত করে।

সিঙ্ক্রোনাইজেশন উন্নতি

ART টিম MonitorEnter/MonitorExit কোড পাথগুলোকে পরিমার্জন করেছে এবং ARMv8-এ প্রচলিত মেমরি ব্যারিয়ারের উপর নির্ভরতা কমিয়ে এনেছে, যেখানে সম্ভব সেগুলোকে নতুন (acquire/release) নির্দেশাবলী দিয়ে প্রতিস্থাপন করেছে।

দ্রুততর স্থানীয় পদ্ধতি

@FastNative এবং @CriticalNative অ্যানোটেশন ব্যবহার করে জাভা নেটিভ ইন্টারফেসে (JNI) দ্রুততর নেটিভ কল করা যায়। এই বিল্ট-ইন ART রানটাইম অপটিমাইজেশনগুলো JNI ট্রানজিশনের গতি বাড়ায় এবং বর্তমানে অপ্রচলিত !bang JNI নোটেশনকে প্রতিস্থাপন করে। এই অ্যানোটেশনগুলো নন-নেটিভ মেথডের উপর কোনো প্রভাব ফেলে না এবং শুধুমাত্র bootclasspath থাকা প্ল্যাটফর্ম জাভা ল্যাঙ্গুয়েজ কোডের জন্য উপলব্ধ (প্লে স্টোর আপডেটের জন্য নয়)।

@FastNative অ্যানোটেশনটি নন-স্ট্যাটিক মেথড সমর্থন করে। যদি কোনো মেথড প্যারামিটার বা রিটার্ন ভ্যালু হিসেবে কোনো jobject অ্যাক্সেস করে, তবে এটি ব্যবহার করুন।

@CriticalNative অ্যানোটেশনটি নেটিভ মেথড চালানোর আরও দ্রুততর একটি উপায় প্রদান করে, তবে এর নিম্নলিখিত সীমাবদ্ধতাগুলো রয়েছে:

  • মেথডগুলো অবশ্যই স্ট্যাটিক হতে হবে—প্যারামিটার, রিটার্ন ভ্যালু বা অন্তর্নিহিত this জন্য কোনো অবজেক্ট ব্যবহার করা যাবে না।
  • নেটিভ মেথডে শুধুমাত্র প্রিমিটিভ টাইপগুলোই পাস করা হয়।
  • নেটিভ মেথডটি তার ফাংশন সংজ্ঞায় JNIEnv এবং jclass প্যারামিটার ব্যবহার করে না।
  • ডাইনামিক JNI লিঙ্কিং-এর উপর নির্ভর না করে, পদ্ধতিটি অবশ্যই RegisterNatives এর মাধ্যমে রেজিস্টার করতে হবে।

@FastNative নেটিভ মেথডের পারফরম্যান্স ৩ গুণ পর্যন্ত এবং @CriticalNative ৫ গুণ পর্যন্ত উন্নত করতে পারে। উদাহরণস্বরূপ, একটি Nexus 6P ডিভাইসে পরিমাপ করা একটি JNI ট্রানজিশন:

জাভা নেটিভ ইন্টারফেস (JNI) আহ্বান সম্পাদনের সময় (ন্যানোসেকেন্ডে)
নিয়মিত জেএনআই ১১৫
!ব্যাং জেএনআই ৬০
@FastNative ৩৫
@CriticalNative ২৫