পাঠ ৩৬ · ৫৬-এর মধ্যে · মডিউল ৮
Home / Courses / Operating Systems (OS) / ফ্রেম অ্যালোকেশন স্ট্র্যাটেজি

ফ্রেম অ্যালোকেশন স্ট্র্যাটেজি

Frame allocation strategies
৭ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • ইকুয়াল ও প্রোপরশনাল ফ্রেম অ্যালোকেশন স্ট্র্যাটেজি এবং তাদের সীমাবদ্ধতা
  • লোকাল বনাম গ্লোবাল রিপ্লেসমেন্ট স্কোপ — একটি স্বতন্ত্র, গুরুত্বপূর্ণ অক্ষ
  • Python-এ প্রকৃত প্রোপরশনাল অ্যালোকেশন গণনা করা এবং রাউন্ডিং-জনিত বাস্তবতা যাচাই করা
  • M8-এর সবগুলো পাঠ (ডিমান্ড পেজিং থেকে ফ্রেম অ্যালোকেশন পর্যন্ত) কীভাবে একটি সম্পূর্ণ ছবি তৈরি করে তার সংক্ষিপ্তসার

১ · কতগুলো ফ্রেম কোন প্রসেসকে দেওয়া উচিত?

L33-L34-এ আমরা দেখেছি একটি একক প্রসেসের জন্য কোন পেজ রিপ্লেস করা উচিত। কিন্তু বাস্তবে একসাথে অনেক প্রসেস চলে, এবং ফিজিক্যাল ফ্রেমের সংখ্যা সীমিত। তাই একটি আরও মৌলিক প্রশ্ন আগে থেকেই সমাধান করতে হয়: ফ্রেম অ্যালোকেশন (Frame Allocation)Frame Allocationমোট সীমিত ফিজিক্যাল ফ্রেম একাধিক প্রসেসের মধ্যে কীভাবে ভাগ করে দেওয়া হবে তা ঠিক করার নিয়ম। — প্রতিটি প্রসেসকে ঠিক কতগুলো ফ্রেম দেওয়া হবে? খুব কম ফ্রেম দিলে সেই প্রসেস ক্রমাগত ফল্ট ঘটাবে (L35-এর থ্র্যাশিংয়ের ঝুঁকি); সব প্রসেসকে উদারভাবে বেশি দিতে গেলে মোট ফ্রেম ফুরিয়ে যাবে।

২ · ইকুয়াল বনাম প্রোপরশনাল অ্যালোকেশন

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

প্রোপরশনাল অ্যালোকেশন ইকুয়াল অ্যালোকেশনের চেয়ে অবশ্যই ন্যায্যতর, কিন্তু এটিরও একটি সীমাবদ্ধতা আছে — এটি শুধু প্রসেসের মোট আকার দেখে, তার বর্তমান প্রকৃত প্রয়োজন (L35-এর ওয়ার্কিং সেট) দেখে না। একটি বিশাল প্রোগ্রাম যদি এই মুহূর্তে তার একটি ছোট অংশ নিয়েই কাজ করে, প্রোপরশনাল অ্যালোকেশন তবুও তাকে তার পুরো আকারের অনুপাতে ফ্রেম দেবে — যার কিছু অংশ হয়তো আসলে অব্যবহৃত থেকে যাবে।

৩ · গ্লোবাল বনাম লোকাল রিপ্লেসমেন্ট স্কোপ

"কতগুলো ফ্রেম" প্রশ্নের পাশাপাশি আরেকটি স্বতন্ত্র প্রশ্ন আছে — একটি প্রসেসে পেজ ফল্ট ঘটলে, রিপ্লেসমেন্ট অ্যালগরিদম (L33-L34) কি শুধু সেই প্রসেসের নিজের ফ্রেমের মধ্যেই একটি ভিকটিম খুঁজবে, নাকি সিস্টেমের যেকোনো প্রসেসের ফ্রেম থেকে?

লোকাল রিপ্লেসমেন্ট
একটি প্রসেস শুধু তার নিজের বরাদ্দকৃত ফ্রেম থেকেই একটি পেজ সরাতে পারে — প্রতিটি প্রসেসের পারফরম্যান্স প্রেডিক্টেবল থাকে, কিন্তু অন্য প্রসেসের অলস ফ্রেম "ধার" করা যায় না, এমনকি প্রচুর ফাঁকা ফ্রেম থাকলেও।
গ্লোবাল রিপ্লেসমেন্ট
যেকোনো প্রসেসের যেকোনো ফ্রেম থেকে সরানো যায় — সামগ্রিক মেমরি ইউটিলাইজেশন ভালো হয়, কিন্তু একটি প্রসেসের আচরণ (যেমন একটি মেমরি-ক্ষুধার্ত প্রসেস) এখন অপ্রত্যাশিতভাবে অন্য প্রসেসের পারফরম্যান্সকেও প্রভাবিত করতে পারে।
এটি একটি সরাসরি বাস্তব ট্রেড-অফ: প্রেডিক্টেবিলিটি (লোকাল) বনাম সামগ্রিক দক্ষতা (গ্লোবাল)। বেশিরভাগ আধুনিক সাধারণ-উদ্দেশ্য OS গ্লোবাল রিপ্লেসমেন্টের কাছাকাছি কোনো নীতি ব্যবহার করে, কারণ গড়ে এটি মেমরি বেশি কার্যকরভাবে ব্যবহার করে — যদিও এর অর্থ একটি প্রসেসের পারফরম্যান্স আরেকটি প্রসেসের আচরণের ওপর নির্ভরশীল হয়ে যায়।

৪ · কোডে: প্রোপরশনাল অ্যালোকেশন গণনা

নিচের কোড সেলে একটি proportional_allocation() ফাংশন — প্রতিটি প্রসেসের নাম ও ভার্চুয়াল আকারের তালিকা এবং মোট ফ্রেম সংখ্যা দিলে, প্রতিটি প্রসেসের আনুপাতিক ফ্রেম-ভাগ গণনা করে। প্রথম উদাহরণে ভিন্ন আকারের প্রসেস, দ্বিতীয় উদাহরণে সমান আকারের প্রসেস কিন্তু এমন একটি ফ্রেম সংখ্যা যা রাউন্ডিংয়ের একটি বাস্তব সীমাবদ্ধতা দেখায়।

Python
# প্রোপরশনাল ফ্রেম অ্যালোকেশন -- বাস্তব প্রসেস আকার নয়, টয় ভার্চুয়াল-সাইজ ডেটা

def proportional_allocation(processes, total_frames):
    """processes: [(name, virtual_size), ...] -- প্রতিটি প্রসেসের আনুপাতিক ফ্রেম-ভাগ গণনা।"""
    total_size = sum(size for _, size in processes)
    allocation = {}
    for name, size in processes:
        allocation[name] = round(total_frames * size / total_size)
    return allocation


# --- উদাহরণ ১: ভিন্ন ভিন্ন আকারের ৩টি প্রসেস ---
processes_1 = [("P1", 200), ("P2", 300), ("P3", 500)]
TOTAL_FRAMES_1 = 20

alloc_1 = proportional_allocation(processes_1, TOTAL_FRAMES_1)
print(f"উদাহরণ ১ -- প্রসেস: {processes_1}, মোট ফ্রেম: {TOTAL_FRAMES_1}")
for name, frames in alloc_1.items():
    print(f"  {name}: {frames} ফ্রেম বরাদ্দ")
print("  যোগফল:", sum(alloc_1.values()))

print()

# --- উদাহরণ ২: সমান আকারের ৩টি প্রসেস, কিন্তু ফ্রেম সংখ্যা ৩ দিয়ে নিঃশেষে বিভাজ্য নয় ---
processes_2 = [("Q1", 1000), ("Q2", 1000), ("Q3", 1000)]
TOTAL_FRAMES_2 = 10

alloc_2 = proportional_allocation(processes_2, TOTAL_FRAMES_2)
print(f"উদাহরণ ২ -- প্রসেস: {processes_2}, মোট ফ্রেম: {TOTAL_FRAMES_2}")
for name, frames in alloc_2.items():
    print(f"  {name}: {frames} ফ্রেম বরাদ্দ")

total_allocated = sum(alloc_2.values())
leftover = TOTAL_FRAMES_2 - total_allocated
print(f"  যোগফল: {total_allocated} (মোট উপলব্ধ {TOTAL_FRAMES_2}-এর মধ্যে {leftover}টি ফ্রেম রাউন্ডিংয়ের কারণে অবণ্টিত থেকে গেল)")

    
উদাহরণ ১-এ ২০টি ফ্রেম ২০০:৩০০:৫০০ অনুপাতে ঠিক ৪:৬:১০ ভাগ হয়ে যায় (যোগফল ২০, নিখুঁত)। কিন্তু উদাহরণ ২-এ ৩টি সমান-আকারের প্রসেস ১০টি ফ্রেম সমান ভাগ করতে গেলে প্রতিটি পায় $10/3 = 3.33...$, যা রাউন্ড করে ৩ হয়ে যায় — তিনটি মিলে মোট ৯টি ফ্রেম বরাদ্দ হয়, ১টি ফ্রেম রাউন্ডিংয়ের কারণে কাউকে দেওয়া হয়নি। বাস্তব OS-গুলো সাধারণত এই অবণ্টিত ফ্রেমগুলো একটি নির্দিষ্ট নিয়মে (যেমন সবচেয়ে বড় প্রসেসকে) বাড়তি দিয়ে সমন্বয় করে।
মূল কথা · M8-এর সম্পূর্ণ ছবি

এই পাঠ দিয়ে M8 (ভার্চুয়াল মেমরি) সম্পূর্ণ হলো। L32 দেখিয়েছে কখন একটি পেজ মেমরিতে আনা হয় (ডিমান্ড পেজিং); L33-L34 দেখিয়েছে মেমরি পূর্ণ থাকলে কাকে সরানো হবে (FIFO, Optimal, LRU); L35 দেখিয়েছে যথেষ্ট ফ্রেম না থাকলে এই সবকিছুই কেন ভেঙে পড়ে (থ্র্যাশিং); আর এই পাঠ দেখাল প্রথমেই কতগুলো ফ্রেম কোন প্রসেসকে দেওয়া উচিত। এই চারটি প্রশ্ন একসাথেই একটি সম্পূর্ণ ভার্চুয়াল মেমরি সিস্টেমের নকশা তৈরি করে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ প্রোপরশনাল অ্যালোকেশন ইকুয়াল অ্যালোকেশনের চেয়ে ভালো হলেও, L35-এর ওয়ার্কিং সেট মডেলের তুলনায় এটি কীভাবে এখনও অসম্পূর্ণ?

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

প্র ০২ গ্লোবাল রিপ্লেসমেন্টে "একটি প্রসেসের আচরণ আরেকটি প্রসেসের পারফরম্যান্স প্রভাবিত করে" — একটি বাস্তব উদাহরণ দিন।

ধরুন দুটো প্রসেস A ও B চলছে, প্রতিটি স্বাভাবিকভাবে ভালো পারফর্ম করছিল নিজস্ব ফ্রেম নিয়ে। হঠাৎ প্রসেস A একটি বিশাল ডেটাসেট স্ক্যান করা শুরু করল (অনেক নতুন, ভিন্ন পেজ অ্যাক্সেস) — গ্লোবাল রিপ্লেসমেন্টে A-এর এই নতুন পেজ ফল্টগুলো B-এর ফ্রেমকেও এভিক্ট করে ফেলতে পারে, যদিও B নিজে কিছুই ভিন্নভাবে করেনি। ফলে B হঠাৎ বেশি পেজ ফল্ট ঘটাতে শুরু করবে — সম্পূর্ণ A-এর আচরণের কারণে। লোকাল রিপ্লেসমেন্টে এটি ঘটত না, কারণ A শুধু নিজের ফ্রেমের মধ্যেই সীমাবদ্ধ থাকত।

প্র ০৩ উপরের কোডের উদাহরণ ২-এ ১টি ফ্রেম "অবণ্টিত" থেকে গেল বলা হচ্ছে — বাস্তবে এই ফ্রেমটির কী হয় বলে মনে করেন?

বাস্তব OS কখনোই সত্যিকারের একটি ফ্রেম "নষ্ট" করে ফেলে রাখে না — round()-এর কারণে তৈরি হওয়া এই ছোট পার্থক্যটি সাধারণত একটি নির্দিষ্ট নিয়মে সমন্বয় করা হয়, যেমন অবশিষ্ট ফ্রেম(গুলো) সবচেয়ে বড় প্রসেসকে (বা সবচেয়ে বেশি ফল্ট ঘটাচ্ছে এমন প্রসেসকে) দিয়ে দেওয়া, অথবা একটি সাধারণ "ফ্রি ফ্রেম পুল"-এ রেখে দেওয়া যা যেকোনো প্রসেসের পরবর্তী ফল্টে ব্যবহার করা যাবে। মূল শিক্ষা হলো — গাণিতিক আনুপাতিকতা সবসময় পূর্ণসংখ্যায় নিখুঁতভাবে ভাগ হয় না, তাই বাস্তবায়নে এই প্রান্তিক পরিস্থিতি সামলানোর একটি নিয়ম থাকা দরকার।

অনুশীলন

  1. পরীক্ষা করুন: উপরের কোড সেলে উদাহরণ ১-এর processes_1-এ একটি নতুন প্রসেস ("P4", 1000) যোগ করুন এবং Run চেপে দেখুন বাকি প্রসেসগুলোর ভাগ কীভাবে কমে যায়।

    নতুন total_size হবে 200+300+500+1000=2000। P4 একাই মোট আকারের অর্ধেক (1000/2000) দখল করায় সে প্রায় ১০টি ফ্রেম (২০-এর অর্ধেক) পাবে, আর P1, P2, P3-এর ভাগ প্রত্যেকেরই কমে যাবে — যদিও তাদের নিজস্ব আকার একদমই বদলায়নি। এটি দেখায় প্রোপরশনাল অ্যালোকেশনে একটি প্রসেসের ভাগ শুধু তার নিজের আকারের ওপর নয়, বাকি সব প্রসেসের সম্মিলিত আকারের ওপরও নির্ভরশীল।

  2. চিন্তা করুন: যদি একটি প্রসেসের ন্যূনতম ফ্রেম প্রয়োজন হয় ৩টি (যেমন একটি নির্দিষ্ট instruction সেটের জন্য নূন্যতম কিছু ফ্রেম হার্ডওয়্যারগতভাবে বাধ্যতামূলক), কিন্তু প্রোপরশনাল অ্যালোকেশন তাকে মাত্র ২টি দেয় — তাহলে কী সমস্যা হতে পারে?

    বাস্তব OS-গুলো তাই সবসময় একটি "সর্বনিম্ন ফ্রেম সংখ্যা" নিয়ম প্রয়োগ করে — প্রোপরশনাল/ইকুয়াল হিসাব যা-ই বলুক না কেন, প্রতিটি প্রসেসকে অন্তত তার হার্ডওয়্যার-নির্ধারিত ন্যূনতম ফ্রেম সংখ্যা দেওয়া বাধ্যতামূলক (যেমন একটি জটিল ইন্সট্রাকশনের সবগুলো অপারেন্ড একসাথে ভিন্ন পেজে থাকতে পারে এমন worst-case বিবেচনা করে)। এর কম দিলে সেই প্রসেস কার্যত চলতেই পারবে না — তাই ন্যূনতম বরাদ্দ প্রোপরশনাল/ইকুয়াল হিসাবের ওপর একটি বাধ্যতামূলক নিচের সীমা (floor) হিসেবে কাজ করে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
থ্র্যাশিং ও ওয়ার্কিং সেট মডেল