জিটার-সম্পর্কিত জ্যাঙ্ক সনাক্ত করুন

জিটার হল র্যান্ডম সিস্টেমের আচরণ যা উপলব্ধিযোগ্য কাজকে চলতে বাধা দেয়। এই পৃষ্ঠাটি বর্ণনা করে যে কীভাবে জিটার-সম্পর্কিত জ্যাঙ্ক সমস্যাগুলি সনাক্ত করা যায় এবং সমাধান করা যায়।

অ্যাপ থ্রেড শিডিউলার বিলম্ব

শিডিউলার বিলম্ব হল জিটারের সবচেয়ে সুস্পষ্ট লক্ষণ: একটি প্রক্রিয়া যা চালানো উচিত তা চালানোর যোগ্য করা হয় কিন্তু কিছু উল্লেখযোগ্য সময়ের জন্য চলে না। প্রেক্ষাপট অনুযায়ী বিলম্বের তাৎপর্য পরিবর্তিত হয়। উদাহরণ স্বরূপ:

  • একটি অ্যাপে একটি র্যান্ডম হেল্পার থ্রেড সম্ভবত কোনো সমস্যা ছাড়াই অনেক মিলিসেকেন্ডের জন্য বিলম্বিত হতে পারে।
  • একটি অ্যাপের UI থ্রেড 1-2ms ঝাঁকুনি সহ্য করতে সক্ষম হতে পারে।
  • SCHED_FIFO হিসাবে চলমান ড্রাইভার কেথ্রেডগুলি চালানোর আগে 500us এর জন্য চালানোর যোগ্য হলে সমস্যা হতে পারে।

একটি থ্রেডের চলমান অংশের পূর্ববর্তী নীল দণ্ড দ্বারা সিস্ট্রেসে রানযোগ্য সময় চিহ্নিত করা যেতে পারে। একটি চলমান সময় একটি থ্রেডের জন্য sched_wakeup ইভেন্ট এবং sched_switch ইভেন্টের মধ্যে সময়ের দৈর্ঘ্য দ্বারাও নির্ধারণ করা যেতে পারে যা থ্রেড এক্সিকিউশন শুরুর সংকেত দেয়।

থ্রেড যে খুব দীর্ঘ চালানো

অ্যাপ UI থ্রেডগুলি যেগুলি খুব বেশি সময় ধরে চালানো যায় সেগুলি সমস্যার কারণ হতে পারে৷ লং-লেভেল থ্রেডের দীর্ঘ রানেবল টাইমগুলির সাধারণত বিভিন্ন কারণ থাকে, তবে UI থ্রেড চালানোর যোগ্য সময়কে শূন্যের দিকে ঠেলে দেওয়ার চেষ্টা করার জন্য একই সমস্যাগুলির কিছু সমাধানের প্রয়োজন হতে পারে যেগুলির কারণে নিম্ন স্তরের থ্রেডগুলি দীর্ঘ চালানোর যোগ্য সময়গুলি সৃষ্টি করে। বিলম্ব কমাতে:

  1. থার্মাল থ্রটলিং -এ বর্ণিত cpusets ব্যবহার করুন।
  2. CONFIG_HZ মান বাড়ান।
    • ঐতিহাসিকভাবে, আর্ম এবং আর্ম64 প্ল্যাটফর্মে মান 100 সেট করা হয়েছে। যাইহোক, এটি ইতিহাসের একটি দুর্ঘটনা এবং ইন্টারেক্টিভ ডিভাইসগুলির জন্য ব্যবহার করার জন্য এটি একটি ভাল মান নয়। CONFIG_HZ=100 এর মানে হল একটি জিফি 10ms দীর্ঘ, যার মানে হল CPU-এর মধ্যে লোড ব্যালেন্সিং ঘটতে 20ms (দুই জিফি) সময় লাগতে পারে। এটি একটি লোড করা সিস্টেমে জ্যাঙ্কে উল্লেখযোগ্যভাবে অবদান রাখতে পারে।
    • সাম্প্রতিক ডিভাইসগুলি (Nexus 5X, Nexus 6P, Pixel, এবং Pixel XL) CONFIG_HZ=300 এর সাথে পাঠানো হয়েছে৷ চলমান সময়ের উল্লেখযোগ্যভাবে উন্নতি করার সময় এটির একটি নগণ্য বিদ্যুতের খরচ থাকা উচিত। আপনি যদি CONFIG_HZ পরিবর্তন করার পরে বিদ্যুৎ খরচ বা কর্মক্ষমতা সংক্রান্ত সমস্যায় উল্লেখযোগ্য বৃদ্ধি দেখতে পান, তাহলে সম্ভবত আপনার ড্রাইভারদের একজন মিলিসেকেন্ডের পরিবর্তে কাঁচা জিফির উপর ভিত্তি করে একটি টাইমার ব্যবহার করছে এবং জিফিতে রূপান্তর করছে। এটি সাধারণত একটি সহজ সমাধান (CONFIG_HZ=300 তে রূপান্তর করার সময় Nexus 5X এবং 6P-এ kgsl টাইমার সমস্যা সংশোধন করে এমন প্যাচ দেখুন)।
    • অবশেষে, আমরা Nexus/Pixel-এ CONFIG_HZ=1000 নিয়ে পরীক্ষা করেছি এবং দেখেছি যে RCU ওভারহেড কমে যাওয়ার কারণে এটি একটি লক্ষণীয় কার্যক্ষমতা এবং পাওয়ার হ্রাস প্রস্তাব করে।

একা এই দুটি পরিবর্তনের সাথে, লোডের অধীনে UI থ্রেড চালানোর যোগ্য সময়ের জন্য একটি ডিভাইসকে আরও ভাল দেখা উচিত।

sys.use_fifo_ui ব্যবহার করুন

আপনি sys.use_fifo_ui প্রপার্টি 1 এ সেট করে UI থ্রেড চালানোর সময়কে শূন্যে চালানোর চেষ্টা করতে পারেন।

সতর্কতা : ভিন্নধর্মী CPU কনফিগারেশনে এই বিকল্পটি ব্যবহার করবেন না যদি না আপনার ক্ষমতা-সচেতন RT শিডিয়ুলার না থাকে। এবং, এই মুহুর্তে, বর্তমানে কোন শিপিং আরটি শিডিউলার সক্ষমতা-সচেতন নয় । আমরা EAS এর জন্য একটিতে কাজ করছি, কিন্তু এটি এখনও উপলব্ধ নয়৷ ডিফল্ট RT শিডিউলারটি সম্পূর্ণরূপে RT অগ্রাধিকারের উপর ভিত্তি করে এবং একটি CPU-তে ইতিমধ্যেই সমান বা উচ্চতর অগ্রাধিকারের একটি RT থ্রেড আছে কিনা।

ফলস্বরূপ, ডিফল্ট RT শিডিউলার আনন্দের সাথে আপনার তুলনামূলকভাবে-দীর্ঘ-চলমান UI থ্রেডকে একটি উচ্চ-ফ্রিকোয়েন্সি বড় কোর থেকে সামান্য কোরে নিয়ে যাবে যদি একই বড় কোরে একটি উচ্চ অগ্রাধিকার FIFO kthread জেগে ওঠে। এটি উল্লেখযোগ্য কর্মক্ষমতা রিগ্রেশন চালু করবে । যেহেতু এই বিকল্পটি এখনও একটি শিপিং অ্যান্ড্রয়েড ডিভাইসে ব্যবহার করা হয়নি, আপনি যদি এটি ব্যবহার করতে চান তবে আপনাকে এটি যাচাই করতে সহায়তা করার জন্য Android পারফরম্যান্স টিমের সাথে যোগাযোগ করুন৷

যখন sys.use_fifo_ui সক্ষম করা থাকে, তখন ActivityManager শীর্ষ অ্যাপের UI থ্রেড এবং RenderThread (দুটি সর্বাধিক UI-গুরুত্বপূর্ণ থ্রেড) ট্র্যাক করে এবং সেই থ্রেডগুলিকে SCHED_OTHER-এর পরিবর্তে SCHED_FIFO করে। এটি কার্যকরভাবে UI এবং RenderThreads থেকে জিটার দূর করে; এই বিকল্পটি দিয়ে আমরা যে ট্রেসগুলি সংগ্রহ করেছি তা মিলিসেকেন্ডের পরিবর্তে মাইক্রোসেকেন্ডের ক্রম অনুসারে চালানোর যোগ্য সময় দেখায়।

যাইহোক, যেহেতু RT লোড ব্যালেন্সার ক্ষমতা-সচেতন ছিল না, তাই অ্যাপ স্টার্টআপ পারফরম্যান্সে 30% হ্রাস পেয়েছিল কারণ অ্যাপটি শুরু করার জন্য দায়ী UI থ্রেডটি 2.1Ghz গোল্ড ক্রিও কোর থেকে 1.5GHz সিলভার ক্রিও কোরে সরানো হবে। . একটি ক্ষমতা-সচেতন RT লোড ব্যালেন্সারের সাথে, আমরা বাল্ক অপারেশনে সমতুল্য পারফরম্যান্স এবং আমাদের অনেক UI বেঞ্চমার্কে 95 তম এবং 99 তম পার্সেন্টাইল ফ্রেম সময়ে 10-15% হ্রাস দেখতে পাই।

ট্রাফিক ব্যাহত

যেহেতু ARM প্ল্যাটফর্মগুলি শুধুমাত্র ডিফল্টরূপে CPU 0 তে বাধা প্রদান করে, আমরা একটি IRQ ব্যালেন্সার (Qualcomm প্ল্যাটফর্মে irqbalance বা msm_irqbalance) ব্যবহার করার পরামর্শ দিই।

পিক্সেল ডেভেলপমেন্টের সময়, আমরা জ্যাঙ্ক দেখেছি যা সরাসরি বাধা সহ অপ্রতিরোধ্য CPU 0 এর জন্য দায়ী করা যেতে পারে। উদাহরণস্বরূপ, যদি mdss_fb0 থ্রেডটি CPU 0 এ নির্ধারিত হয়, তাহলে স্ক্যানআউটের প্রায় সাথে সাথেই ডিসপ্লে দ্বারা ট্রিগার হওয়া একটি বাধার কারণে জ্যাঙ্ক হওয়ার সম্ভাবনা অনেক বেশি ছিল। mdss_fb0 খুব শক্ত সময়সীমার সাথে তার নিজের কাজের মাঝখানে থাকবে, এবং তারপর এটি MDSS ইন্টারাপ্ট হ্যান্ডলারের কাছে কিছু সময় হারাবে। প্রাথমিকভাবে, আমরা বিঘ্নের সাথে বিবাদ এড়াতে mdss_fb0 থ্রেডের CPU 1-3-এ CPU অ্যাফিনিটি সেট করে এটি ঠিক করার চেষ্টা করেছি, কিন্তু তারপর আমরা বুঝতে পেরেছি যে আমরা এখনও msm_irqbalance সক্ষম করিনি। msm_irqbalance সক্রিয় করার সাথে, জ্যাঙ্ক লক্ষণীয়ভাবে উন্নত হয়েছে এমনকি যখন mdss_fb0 এবং MDSS ইন্টারাপ্ট উভয়ই একই CPU-তে ছিল অন্যান্য বাধা থেকে বিরোধ কম হওয়ার কারণে।

এটি systrace এ চিহ্নিত করা যেতে পারে নির্ধারিত অংশের পাশাপাশি irq বিভাগটি দেখে। নির্ধারিত বিভাগটি দেখায় কি নির্ধারণ করা হয়েছে, কিন্তু irq বিভাগে একটি ওভারল্যাপিং অঞ্চলের অর্থ হল যে একটি বিঘ্নিত হচ্ছে সেই সময়ে স্বাভাবিকভাবে নির্ধারিত প্রক্রিয়ার পরিবর্তে। আপনি যদি দেখেন যে একটি বিঘ্নিত হওয়ার সময় উল্লেখযোগ্য অংশ নেওয়া হয়েছে, আপনার বিকল্পগুলির মধ্যে রয়েছে:

  • বিঘ্নিত হ্যান্ডলার দ্রুত করুন.
  • প্রথম স্থানে ঘটতে বাধা রোধ করুন.
  • বাধার ফ্রিকোয়েন্সি পরিবর্তন করুন যাতে অন্যান্য নিয়মিত কাজের সাথে এটি হস্তক্ষেপ করতে পারে (যদি এটি একটি নিয়মিত বাধা হয়)।
  • সরাসরি ইন্টারাপ্টের সিপিইউ অ্যাফিনিটি সেট করুন এবং এটিকে ভারসাম্য থেকে আটকান।
  • ইন্টারাপ্ট এড়াতে ইন্টারাপ্ট যে থ্রেডে হস্তক্ষেপ করছে তার CPU অ্যাফিনিটি সেট করুন।
  • ইন্টারাপ্টকে কম লোডেড CPU-তে সরাতে ইন্টারাপ্ট ব্যালেন্সারের উপর নির্ভর করুন।

সিপিইউ অ্যাফিনিটি সেট করা সাধারণত সুপারিশ করা হয় না তবে নির্দিষ্ট ক্ষেত্রে উপযোগী হতে পারে। সাধারণভাবে, বেশিরভাগ সাধারণ বাধাগুলির জন্য সিস্টেমের অবস্থার ভবিষ্যদ্বাণী করা খুব কঠিন, তবে আপনার যদি এমন একটি নির্দিষ্ট শর্ত থাকে যা নির্দিষ্ট বাধাগুলিকে ট্রিগার করে যেখানে সিস্টেম স্বাভাবিকের চেয়ে বেশি সীমাবদ্ধ থাকে (যেমন VR), স্পষ্ট CPU অ্যাফিনিটি হতে পারে একটি ভাল সমাধান হতে.

দীর্ঘ সফ্টরক্স

একটি সফ্টির্ক চলমান অবস্থায়, এটি প্রিম্পশন অক্ষম করে। softirqs কার্নেলের মধ্যে অনেক জায়গায় ট্রিগার করা যেতে পারে এবং একটি ব্যবহারকারী প্রক্রিয়ার ভিতরে চলতে পারে। যদি যথেষ্ট softirq কার্যকলাপ থাকে, ব্যবহারকারীর প্রক্রিয়াগুলি softirqs চালানো বন্ধ করবে এবং ksoftirqd softirqs চালানোর জন্য এবং ভারসাম্য ভারসাম্যপূর্ণ হতে জেগে উঠবে। সাধারণত, এই জরিমানা. যাইহোক, একটি একক খুব দীর্ঘ softirq সিস্টেমকে ধ্বংস করতে পারে।


softirqs একটি ট্রেসের irq বিভাগের মধ্যে দৃশ্যমান, তাই তারা সনাক্ত করা সহজ হয় যদি ট্রেসিং করার সময় সমস্যাটি পুনরুত্পাদন করা যায়। যেহেতু একটি softirq একটি ব্যবহারকারীর প্রক্রিয়ার মধ্যে চলতে পারে, একটি খারাপ softirq কোন সুস্পষ্ট কারণ ছাড়াই একটি ব্যবহারকারী প্রক্রিয়ার ভিতরে অতিরিক্ত রানটাইম হিসাবে প্রকাশ করতে পারে। আপনি যদি এটি দেখতে পান তবে সফ্টইর্কগুলি দোষী কিনা তা দেখতে irq বিভাগটি পরীক্ষা করুন।

প্রিমম্পশন বা IRQs ত্যাগকারী ড্রাইভারগুলি খুব দীর্ঘ সময় ধরে নিষ্ক্রিয়

প্রিম্পশন অক্ষম করা বা খুব দীর্ঘ (দশ মিলিসেকেন্ড) জন্য বাধার ফলে জ্যাঙ্ক হয়। সাধারণত, জ্যাঙ্ক একটি থ্রেড হিসাবে প্রদর্শিত হয় যা চালানোর যোগ্য হয়ে উঠছে কিন্তু একটি নির্দিষ্ট CPU তে চলছে না, এমনকি যদি রানযোগ্য থ্রেডটি অন্যান্য থ্রেডের তুলনায় উল্লেখযোগ্যভাবে বেশি অগ্রাধিকার (বা SCHED_FIFO) হয়।

কিছু নির্দেশিকা:

  • চলমান থ্রেড যদি SCHED_FIFO হয় এবং চলমান থ্রেড SCHED_OTHER হয়, চলমান থ্রেডের প্রিম্পশন বা ইন্টারাপ্ট অক্ষম থাকে।
  • যদি রানেবল থ্রেডটি চলমান থ্রেডের (120) তুলনায় উল্লেখযোগ্যভাবে বেশি অগ্রাধিকার (100) হয়, তবে রানযোগ্য থ্রেডটি যদি দুই মুহূর্তের মধ্যে না চলে তবে চলমান থ্রেডের প্রিম্পশন বা বাধা নিষ্ক্রিয় করা হতে পারে।
  • যদি রানেবল থ্রেড এবং চলমান থ্রেডের অগ্রাধিকার একই থাকে, তাহলে চলমান থ্রেডের প্রিম্পশন বা ইন্টারাপ্ট অক্ষম করা যেতে পারে যদি রানেবল থ্রেড 20ms এর মধ্যে না চলে।

মনে রাখবেন যে একটি ইন্টারাপ্ট হ্যান্ডলার চালানো আপনাকে অন্যান্য ইন্টারাপ্ট পরিষেবা দিতে বাধা দেয়, যা প্রিম্পশনকেও অক্ষম করে।


আপত্তিকর অঞ্চল শনাক্ত করার জন্য আরেকটি বিকল্প হল প্রিএমপ্টিরকসফ ট্রেসার ( ডাইনামিক ftrace ব্যবহার করা দেখুন)। এই ট্রেসারটি একটি নিরবচ্ছিন্ন অঞ্চলের (যেমন ফাংশনের নাম) এর মূল কারণ সম্পর্কে অনেক বেশি অন্তর্দৃষ্টি দিতে পারে, তবে সক্ষম করার জন্য আরও আক্রমণাত্মক কাজের প্রয়োজন। যদিও এটির কার্যক্ষমতার প্রভাব বেশি হতে পারে, এটি অবশ্যই চেষ্টা করার মতো।

কাজের সারিগুলির ভুল ব্যবহার

ইন্টারপ্ট হ্যান্ডলারদের প্রায়ই এমন কাজ করতে হয় যা একটি ইন্টারাপ্ট প্রেক্ষাপটের বাইরে চলতে পারে, যা কার্নেলের বিভিন্ন থ্রেডে কাজ করতে সক্ষম করে। একজন ড্রাইভার ডেভেলপার লক্ষ্য করতে পারে যে কার্নেলের একটি খুব সুবিধাজনক সিস্টেম-ওয়াইড অ্যাসিঙ্ক্রোনাস টাস্ক কার্যকারিতা রয়েছে যাকে ওয়ার্ককিউ বলা হয় এবং এটি বাধা-সম্পর্কিত কাজের জন্য ব্যবহার করতে পারে।

যাইহোক, কাজের সারি প্রায় সবসময় এই সমস্যার জন্য ভুল উত্তর কারণ তারা সবসময় SCHED_OTHER হয়। অনেক হার্ডওয়্যার বাধা কার্যক্ষমতার জটিল পথে রয়েছে এবং অবিলম্বে চালানো উচিত। কাজের সারি কখন চালানো হবে তার কোন নিশ্চয়তা নেই। যতবারই আমরা পারফরম্যান্সের সমালোচনামূলক পথে একটি কাজের সারি দেখেছি, ডিভাইসটি নির্বিশেষে এটি বিক্ষিপ্ত জ্যাঙ্কের উত্স হয়েছে। Pixel-এ, একটি ফ্ল্যাগশিপ প্রসেসর সহ, আমরা দেখেছি যে ডিভাইসটি লোডের অধীনে থাকলে একটি একক ওয়ার্ককিউ 7ms পর্যন্ত বিলম্বিত হতে পারে যদি সিস্টেমে চলমান শিডিউলারের আচরণ এবং অন্যান্য জিনিসগুলির উপর নির্ভর করে।

একটি ওয়ার্ক কিউর পরিবর্তে, যে ড্রাইভারগুলিকে একটি পৃথক থ্রেডের মধ্যে বাধার মতো কাজ পরিচালনা করতে হবে তাদের নিজস্ব SCHED_FIFO kthread তৈরি করা উচিত। kthread_work ফাংশনগুলির সাথে এটি করতে সাহায্যের জন্য, এই প্যাচটি পড়ুন।

ফ্রেমওয়ার্ক লক বিতর্ক

ফ্রেমওয়ার্ক লক বিরোধ জ্যাঙ্ক বা অন্যান্য কর্মক্ষমতা সমস্যার একটি উৎস হতে পারে। এটি সাধারণত ActivityManagerService লক দ্বারা সৃষ্ট হয় তবে অন্যান্য লকগুলিতেও দেখা যায়। উদাহরণস্বরূপ, PowerManagerService লক কার্যক্ষমতার উপর স্ক্রীনকে প্রভাবিত করতে পারে। আপনি যদি আপনার ডিভাইসে এটি দেখতে পান তবে এর কোনও ভাল সমাধান নেই কারণ এটি কেবল কাঠামোর স্থাপত্যগত উন্নতির মাধ্যমে উন্নত করা যেতে পারে। যাইহোক, আপনি যদি system_server-এর ভিতরে চলে এমন কোড পরিবর্তন করে থাকেন, তাহলে দীর্ঘ সময় ধরে লক রাখা এড়াতে গুরুত্বপূর্ণ, বিশেষ করে ActivityManagerService লক।

বাইন্ডার লক বিতর্ক

ঐতিহাসিকভাবে, বাইন্ডারের একটি একক গ্লোবাল লক ছিল। যদি একটি বাইন্ডার লেনদেন চালানোর থ্রেডটি লকটি ধরে রাখার সময় পূর্বনির্ধারিত হয়, তবে মূল থ্রেডটি লকটি প্রকাশ না করা পর্যন্ত অন্য কোনও থ্রেড বাইন্ডার লেনদেন করতে পারে না। এইটা খারাপ; বাইন্ডার কনটেশন ডিসপ্লেতে UI আপডেট পাঠানো সহ সিস্টেমের সমস্ত কিছুকে ব্লক করতে পারে (UI থ্রেডগুলি বাইন্ডারের মাধ্যমে SurfaceFlinger এর সাথে যোগাযোগ করে)।

অ্যান্ড্রয়েড 6.0 বাইন্ডার লকটি ধরে রাখার সময় প্রিম্পশন অক্ষম করে এই আচরণটি উন্নত করতে বেশ কয়েকটি প্যাচ অন্তর্ভুক্ত করেছে। এটি নিরাপদ ছিল কারণ বাইন্ডার লকটি প্রকৃত রানটাইমের কয়েক মাইক্রোসেকেন্ডের জন্য রাখা উচিত। এটি অপ্রতিরোধ্য পরিস্থিতিতে নাটকীয়ভাবে পারফরম্যান্সকে উন্নত করে এবং বাইন্ডার লকটি ধরে রাখার সময় বেশিরভাগ সময়সূচী সুইচ প্রতিরোধ করে বিরোধ প্রতিরোধ করে। যাইহোক, বাইন্ডার লক ধরে রাখার পুরো রানটাইমের জন্য প্রিম্পশন নিষ্ক্রিয় করা যায়নি, যার অর্থ হল যে কাজগুলি ঘুমাতে পারে (যেমন copy_from_user) এর জন্য প্রিম্পশন সক্রিয় করা হয়েছিল, যা মূল ক্ষেত্রের মতো একই প্রিম্পশন ঘটাতে পারে। আমরা যখন প্যাচগুলিকে উজানে পাঠাই, তারা অবিলম্বে আমাদের বলেছিল যে এটি ইতিহাসের সবচেয়ে খারাপ ধারণা। (আমরা তাদের সাথে একমত, কিন্তু আমরা জ্যাঙ্ক প্রতিরোধের দিকে প্যাচগুলির কার্যকারিতা নিয়ে তর্ক করতে পারিনি।)

একটি প্রক্রিয়ার মধ্যে fd বিরোধ

এটি বিরল। আপনার জ্যাঙ্ক সম্ভবত এটি দ্বারা সৃষ্ট হয় না.

এতে বলা হয়েছে, একই fd লেখার প্রক্রিয়ার মধ্যে যদি আপনার একাধিক থ্রেড থাকে, তাহলে এই fd-এ বিতর্ক দেখা সম্ভব, তবে Pixel আনার সময় আমরা এটি শুধুমাত্র একটি পরীক্ষার সময় দেখেছি যেখানে কম-অগ্রাধিকার থ্রেডগুলি সমস্ত CPU দখল করার চেষ্টা করেছিল সময় যখন একই প্রক্রিয়ার মধ্যে একটি একক উচ্চ-প্রধান থ্রেড চলছিল। সমস্ত থ্রেড ট্রেস মার্কার fd-এ লেখা ছিল এবং উচ্চ-অগ্রাধিকারের থ্রেড ট্রেস মার্কার fd-এ ব্লক হয়ে যেতে পারে যদি একটি নিম্ন-অগ্রাধিকার থ্রেড fd লক ধরে থাকে এবং তারপরে প্রিমম্প করা হয়। যখন নিম্ন-অগ্রাধিকার থ্রেড থেকে ট্রেসিং অক্ষম করা হয়েছিল, তখন কোন কর্মক্ষমতা সমস্যা ছিল না।

আমরা অন্য কোনো পরিস্থিতিতে এটি পুনরুত্পাদন করতে সক্ষম ছিলাম না, তবে ট্রেসিং করার সময় পারফরম্যান্সের সমস্যাগুলির সম্ভাব্য কারণ হিসাবে এটি নির্দেশ করা মূল্যবান।

অপ্রয়োজনীয় CPU নিষ্ক্রিয় রূপান্তর

আইপিসি, বিশেষ করে মাল্টি-প্রসেস পাইপলাইনগুলির সাথে ডিল করার সময়, নিম্নলিখিত রানটাইম আচরণে বৈচিত্র দেখা যায়:

  1. থ্রেড A CPU 1 এ চলে।
  2. থ্রেড A জেগে ওঠে থ্রেড বি।
  3. থ্রেড বি CPU 2 এ চলতে শুরু করে।
  4. থ্রেড A অবিলম্বে ঘুমাতে যায়, থ্রেড B দ্বারা জাগ্রত হতে যখন থ্রেড B তার বর্তমান কাজ শেষ করে।

ওভারহেডের একটি সাধারণ উৎস হল ধাপ 2 এবং 3 এর মধ্যে। CPU 2 নিষ্ক্রিয় থাকলে, থ্রেড B চালানোর আগে এটিকে একটি সক্রিয় অবস্থায় ফিরিয়ে আনতে হবে। SOC এবং নিষ্ক্রিয়তা কতটা গভীর তার উপর নির্ভর করে, থ্রেড B চালু হওয়ার আগে এটি দশ মাইক্রোসেকেন্ড হতে পারে। যদি IPC-এর প্রতিটি দিকের প্রকৃত রানটাইম ওভারহেডের যথেষ্ট কাছাকাছি হয়, তাহলে সেই পাইপলাইনের সামগ্রিক কর্মক্ষমতা উল্লেখযোগ্যভাবে CPU নিষ্ক্রিয় ট্রানজিশন দ্বারা হ্রাস করা যেতে পারে। অ্যান্ড্রয়েডের জন্য এটিকে আঘাত করার সবচেয়ে সাধারণ জায়গা হল বাইন্ডার লেনদেন এবং অনেক পরিষেবা যা বাইন্ডার ব্যবহার করে তা উপরে বর্ণিত পরিস্থিতির মতো দেখায়।

প্রথমে, আপনার কার্নেল ড্রাইভারগুলিতে wake_up_interruptible_sync() ফাংশনটি ব্যবহার করুন এবং যেকোনো কাস্টম শিডিউলার থেকে এটি সমর্থন করুন। এটিকে একটি প্রয়োজন হিসাবে বিবেচনা করুন, একটি ইঙ্গিত নয়। বাইন্ডার আজ এটি ব্যবহার করে, এবং এটি অপ্রয়োজনীয় CPU নিষ্ক্রিয় রূপান্তর এড়িয়ে সিঙ্ক্রোনাস বাইন্ডার লেনদেনের সাথে অনেক সাহায্য করে।

দ্বিতীয়ত, নিশ্চিত করুন যে আপনার cpuidle ট্রানজিশনের সময়গুলো বাস্তবসম্মত এবং cpuidle গভর্নর এগুলোকে সঠিকভাবে বিবেচনা করছেন। যদি আপনার SOC আপনার গভীরতম নিষ্ক্রিয় অবস্থার মধ্যে এবং বাইরে থ্র্যাশ করছে, আপনি গভীরতম নিষ্ক্রিয় অবস্থায় গিয়ে শক্তি সঞ্চয় করবেন না।

লগিং

লগিং CPU চক্র বা মেমরির জন্য বিনামূল্যে নয়, তাই লগ বাফার স্প্যাম করবেন না। আপনার অ্যাপে (সরাসরি) এবং লগ ডেমনে লগিং খরচ চক্র। আপনার ডিভাইস পাঠানোর আগে যেকোনো ডিবাগিং লগ মুছে ফেলুন।

I/O সমস্যা

I/O ক্রিয়াকলাপগুলি জিটারের সাধারণ উত্স। যদি একটি থ্রেড একটি মেমরি-ম্যাপ করা ফাইল অ্যাক্সেস করে এবং পৃষ্ঠাটি পৃষ্ঠার ক্যাশে না থাকে, তাহলে এটি ত্রুটি করে এবং ডিস্ক থেকে পৃষ্ঠাটি পড়ে। এটি থ্রেডকে ব্লক করে (সাধারণত 10+ ms-এর জন্য) এবং যদি এটি UI রেন্ডারিংয়ের জটিল পথে ঘটে, তাহলে জ্যাঙ্ক হতে পারে। এখানে আলোচনা করার জন্য I/O অপারেশনগুলির অনেকগুলি কারণ রয়েছে, কিন্তু I/O আচরণ উন্নত করার চেষ্টা করার সময় নিম্নলিখিত অবস্থানগুলি পরীক্ষা করুন:

  • পিনার সার্ভিস । Android 7.0 এ যোগ করা হয়েছে, PinnerService পৃষ্ঠা ক্যাশে কিছু ফাইল লক করতে ফ্রেমওয়ার্ক সক্ষম করে। এটি অন্য কোনও প্রক্রিয়ার দ্বারা ব্যবহারের জন্য মেমরিকে সরিয়ে দেয়, তবে যদি এমন কিছু ফাইল থাকে যা নিয়মিত ব্যবহার করার জন্য অগ্রাধিকার হিসাবে পরিচিত, তবে সেই ফাইলগুলিকে লক করা কার্যকর হতে পারে।

    Android 7.0 চালিত Pixel এবং Nexus 6P ডিভাইসে, আমরা চারটি ফাইল লক করেছি:
    • /system/framework/arm64/boot-framework.oat
    • /system/framework/oat/arm64/services.odex
    • /system/framework/arm64/boot.oat
    • /system/framework/arm64/boot-core-libart.oat
    এই ফাইলগুলি বেশিরভাগ অ্যাপ এবং সিস্টেম_সার্ভার দ্বারা ক্রমাগত ব্যবহার করা হয়, তাই সেগুলিকে পেজ আউট করা উচিত নয়৷ বিশেষ করে, আমরা দেখেছি যে যদি সেগুলির মধ্যে যেকোনও পেজ আউট করা হয়, সেগুলি আবার পেজ করা হবে এবং একটি হেভিওয়েট অ্যাপ থেকে স্যুইচ করার সময় জ্যাঙ্কের কারণ হবে৷
  • জোড়া লাগানো . I/O সমস্যার আরেকটি সম্ভাব্য কারণ। আমরা CPU-ভিত্তিক এনক্রিপশন বা DMA এর মাধ্যমে অ্যাক্সেসযোগ্য হার্ডওয়্যার ব্লক ব্যবহার করার সাথে তুলনা করলে ইনলাইন এনক্রিপশন সেরা পারফরম্যান্স অফার করে। সবচেয়ে গুরুত্বপূর্ণভাবে, ইনলাইন এনক্রিপশন I/O-এর সাথে যুক্ত জট কমায়, বিশেষ করে যখন CPU-ভিত্তিক এনক্রিপশনের সাথে তুলনা করা হয়। যেহেতু পৃষ্ঠা ক্যাশে নিয়ে আসা প্রায়শই UI রেন্ডারিংয়ের জটিল পথে থাকে, তাই CPU-ভিত্তিক এনক্রিপশন সমালোচনামূলক পথে অতিরিক্ত CPU লোড প্রবর্তন করে, যা I/O আনার চেয়ে আরও বেশি ঝাঁকুনি যোগ করে।

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

আক্রমনাত্মক ছোট টাস্ক প্যাকিং

কিছু সময়সূচী আরও বেশি CPU গুলিকে নিষ্ক্রিয় রেখে পাওয়ার খরচ কমানোর চেষ্টা করার জন্য একক CPU কোরে ছোট কাজগুলি প্যাক করার জন্য সহায়তা প্রদান করে। যদিও এটি থ্রুপুট এবং পাওয়ার খরচের জন্য ভাল কাজ করে, এটি বিলম্বের জন্য বিপর্যয়কর হতে পারে। UI রেন্ডারিংয়ের সমালোচনামূলক পথে বেশ কয়েকটি স্বল্প-চলমান থ্রেড রয়েছে যেগুলিকে ছোট হিসাবে বিবেচনা করা যেতে পারে; যদি এই থ্রেডগুলি বিলম্বিত হয় কারণ সেগুলি ধীরে ধীরে অন্যান্য CPU-তে স্থানান্তরিত হয়, তাহলে এটি জ্যাঙ্ক সৃষ্টি করবে । আমরা খুব রক্ষণশীলভাবে ছোট টাস্ক প্যাকিং ব্যবহার করার পরামর্শ দিই।

পৃষ্ঠা ক্যাশে থ্র্যাশিং

পর্যাপ্ত বিনামূল্যের মেমরি ছাড়া একটি ডিভাইস হঠাৎ করে একটি নতুন অ্যাপ খোলার মতো দীর্ঘমেয়াদী অপারেশন করার সময় অত্যন্ত মন্থর হয়ে যেতে পারে। অ্যাপটির একটি ট্রেস প্রকাশ করতে পারে যে এটি একটি নির্দিষ্ট রান চলাকালীন I/O তে ধারাবাহিকভাবে ব্লক করা হয়েছে এমনকি যখন এটি প্রায়শই I/O তে ব্লক করা হয় না। এটি সাধারণত পৃষ্ঠা ক্যাশে থ্র্যাশিংয়ের একটি চিহ্ন, বিশেষ করে কম মেমরির ডিভাইসগুলিতে৷

এটি সনাক্ত করার একটি উপায় হল pagecache ট্যাগ ব্যবহার করে একটি systrace নেওয়া এবং system/extras/pagecache/pagecache.py এ স্ক্রিপ্টে ট্রেস করা। pagecache.py পৃষ্ঠা ক্যাশে ফাইলগুলিকে ম্যাপ করার জন্য পৃথক অনুরোধগুলিকে প্রতি-ফাইলের সমষ্টিগত পরিসংখ্যানে অনুবাদ করে৷ আপনি যদি দেখতে পান যে ডিস্কে থাকা ফাইলটির মোট আকারের চেয়ে একটি ফাইলের বেশি বাইট পড়া হয়েছে, আপনি অবশ্যই পৃষ্ঠা ক্যাশে থ্র্যাশিং হিট করছেন৷

এর অর্থ হল আপনার কাজের চাপের জন্য প্রয়োজনীয় কাজের সেট (সাধারণত একটি একক অ্যাপ প্লাস সিস্টেম_সার্ভার) আপনার ডিভাইসে পৃষ্ঠা ক্যাশে উপলব্ধ মেমরির পরিমাণের চেয়ে বেশি। ফলস্বরূপ, কাজের চাপের একটি অংশ পৃষ্ঠার ক্যাশে প্রয়োজনীয় ডেটা পায়, অদূর ভবিষ্যতে ব্যবহার করা হবে এমন আরেকটি অংশ উচ্ছেদ করা হবে এবং আবার আনতে হবে, যার ফলে লোড না হওয়া পর্যন্ত সমস্যাটি আবার ঘটবে। সম্পন্ন হয়েছে. একটি ডিভাইসে পর্যাপ্ত মেমরি উপলব্ধ না হলে এটি কর্মক্ষমতা সমস্যার মৌলিক কারণ।

পৃষ্ঠার ক্যাশে থ্র্যাশিং ঠিক করার কোন নির্বোধ উপায় নেই, তবে একটি প্রদত্ত ডিভাইসে এটি উন্নত করার চেষ্টা করার কয়েকটি উপায় রয়েছে৷

  • ক্রমাগত প্রক্রিয়ায় কম মেমরি ব্যবহার করুন। ক্রমাগত প্রক্রিয়াগুলির দ্বারা যত কম মেমরি ব্যবহৃত হয়, অ্যাপস এবং পৃষ্ঠা ক্যাশে তত বেশি মেমরি উপলব্ধ।
  • আপনি অপ্রয়োজনীয়ভাবে OS থেকে মেমরি অপসারণ করছেন না তা নিশ্চিত করতে আপনার ডিভাইসের জন্য আপনার কাছে থাকা কার্ভআউটগুলি নিরীক্ষণ করুন৷ আমরা এমন পরিস্থিতিতে দেখেছি যেখানে ডিবাগিংয়ের জন্য ব্যবহৃত কার্ভআউটগুলি দুর্ঘটনাক্রমে শিপিং কার্নেল কনফিগারেশনে রেখে দেওয়া হয়েছিল, দশ মেগাবাইট মেমরি গ্রাস করে। এটি পৃষ্ঠা ক্যাশে থ্র্যাশিং এবং না করার মধ্যে পার্থক্য করতে পারে, বিশেষত কম মেমরির ডিভাইসগুলিতে।
  • আপনি যদি সমালোচনামূলক ফাইলগুলিতে সিস্টেম_সার্ভারে পৃষ্ঠা ক্যাশে থ্র্যাশিং দেখতে পান তবে সেই ফাইলগুলি পিন করার কথা বিবেচনা করুন। এটি অন্য কোথাও মেমরির চাপ বাড়াবে, তবে এটি থ্র্যাশিং এড়াতে যথেষ্ট আচরণ পরিবর্তন করতে পারে।
  • আরও মেমরি মুক্ত রাখার চেষ্টা করতে লোমেমরিকিলার রিটিউন করুন। lowmemorykiller-এর থ্রেশহোল্ডগুলি পরম বিনামূল্যে মেমরি এবং পৃষ্ঠার ক্যাশে উভয়ের উপর ভিত্তি করে তৈরি, তাই প্রদত্ত oom_adj স্তরে প্রসেসগুলিকে যে থ্রেশহোল্ডে মেরে ফেলা হয় তা বাড়ানোর ফলে ব্যাকগ্রাউন্ড অ্যাপের বর্ধিত মৃত্যুর খরচে আরও ভাল আচরণ হতে পারে।
  • ZRAM ব্যবহার করে দেখুন। Pixel-এ 4GB থাকা সত্ত্বেও আমরা পিক্সেলে ZRAM ব্যবহার করি, কারণ এটি খুব কমই ব্যবহৃত নোংরা পৃষ্ঠাগুলিতে সাহায্য করতে পারে।