পারফরম্যান্স মেট্রিক্স — CPI, MIPS ও বেঞ্চমার্কিং
এই পাঠে যা শিখবেন
- এক্সিকিউশন টাইমের "আয়রন ল" সূত্র ও এর প্রতিটি টার্মের নির্ভুল অর্থ
- CPI কীভাবে M6 (ডেটাপাথ) ও M7 (পাইপলাইনিং)-এর সব সিদ্ধান্তকে একটি সংখ্যায় সংশ্লেষিত করে
- MIPS-এর সূত্র, এবং কেন ভিন্ন ISA-র মধ্যে MIPS তুলনা করা প্রায় অর্থহীন
- Python-এ কম্পিউট করা একটি বাস্তব উদাহরণে দেখা — কম MIPS পাওয়া প্রসেসরই কম এক্সিকিউশন টাইমে কাজ শেষ করে
১ · এক্সিকিউশন টাইম — আসল, সবচেয়ে সৎ মেট্রিক
ক্লক স্পিড বা MIPS-এর মতো মেট্রিক আলাদাভাবে দেখলে বিভ্রান্তিকর হতে পারে — বাস্তবে যা সত্যিকার গুরুত্বপূর্ণ তা হলো একটি প্রকৃত workload কতটা সময়ে শেষ হয়। এটাই প্রসেসর পারফরম্যান্সের ধ্রুপদী "আয়রন ল":
$$ExecutionTime = InstructionCount \times CPI \times ClockCycleTime$$
যেখানে InstructionCount হলো প্রোগ্রামটি চালাতে মোট কতগুলো ইনস্ট্রাকশন এক্সিকিউট হয়েছে, CPI হলো গড় প্রতি-ইনস্ট্রাকশন সাইকেল সংখ্যা, আর ClockCycleTime হলো একটি একক ক্লক সাইকেলের সময়কাল (ক্লক রেটের বিপরীত)।
২ · CPI — M6 ও M7-এর সংশ্লেষণ
CPI (Cycles Per Instruction) সরাসরি M6-M7-এ শেখা ডিজাইন সিদ্ধান্তের ফলাফল। M6/L28-এর সিঙ্গেল-সাইকেল ডিজাইনে সংজ্ঞা অনুযায়ী CPI = 1 (প্রতিটি ইনস্ট্রাকশন ঠিক এক সাইকেলে শেষ হয়)। M6/L31-এর মাল্টি-সাইকেল ডিজাইনে CPI ইনস্ট্রাকশন-টাইপ অনুযায়ী পরিবর্তিত হয় (প্রকৃতপক্ষে চালানো ইনস্ট্রাকশন মিক্সের ওজনযুক্ত গড়)। M7/L32-এর আদর্শ পাইপলাইনে CPI 1-এর কাছাকাছি পৌঁছায়, কিন্তু M7/L33-L36-এর হ্যাজার্ড ও স্টল বাস্তব CPI-কে সামান্য 1-এর ওপরে ঠেলে দেয়। এক কথায়: CPI-এর একটি মাত্র সংখ্যায় গোটা M6-M7 মডিউলের ডিজাইন সিদ্ধান্তের প্রতিফলন দেখা যায়।
৩ · MIPS — কেন বিভ্রান্তিকর হতে পারে
$$MIPS = \dfrac{ClockRate}{CPI \times 10^6}$$
MIPS ঐতিহাসিকভাবে জনপ্রিয় একটি মেট্রিক, কিন্তু একা ব্যবহার করলে এটি গুরুতরভাবে বিভ্রান্তিকর — কারণ MIPS হিসাব করে না প্রতিটি ইনস্ট্রাকশন আসলে কতটা কাজ করছে। M5/L23-এর CISC বনাম RISC আলোচনা মনে করুন: একটি CISC ইনস্ট্রাকশন একাধিক কাজ একসাথে করতে পারে (যেমন মেমরি-লোড আর যোগ একই ইনস্ট্রাকশনে), যেখানে একটি RISC ইনস্ট্রাকশন একটিমাত্র সরল কাজ করে — তাই একই প্রোগ্রাম চালাতে RISC-কে সাধারণত বেশি ইনস্ট্রাকশন লাগে। ফলাফল: একটি CISC প্রসেসরের MIPS একটি RISC প্রসেসরের চেয়ে কম হতে পারে, অথচ একই কাজ CISC প্রসেসর কম মোট সময়ে শেষ করতে পারে — কারণ তার লাগে অনেক কম ইনস্ট্রাকশন। তাই ভিন্ন ISA-র মধ্যে MIPS তুলনা করা প্রায় অর্থহীন — এটি একটি genuinely গুরুত্বপূর্ণ, বাস্তব সতর্কতা।
একটি গুরুত্বপূর্ণ গাণিতিক সূক্ষ্মতা স্পষ্ট করা দরকার: যদি একই instruction count-এর একটি কাজ দুই প্রসেসরে চালানো হয়, তাহলে $ExecutionTime = \frac{InstructionCount}{MIPS \times 10^6}$ — অর্থাৎ instruction count স্থির থাকলে বেশি MIPS-ই সবসময় কম সময় দেবে। "কম MIPS তবু কম সময়" এই counter-intuitive ফলাফল তখনই বাস্তবে ঘটে যখন দুই প্রসেসর ভিন্ন instruction count-এ একই কাজ শেষ করে — ঠিক যেমন CISC বনাম RISC-এর ক্ষেত্রে হয়।
নিচের কোড সেলে দুটি হাইপোথেটিক্যাল প্রসেসরের জন্য এক্সিকিউশন টাইম ও MIPS প্রকৃতপক্ষে কম্পিউট করা হবে — যেখানে কম MIPS পাওয়া প্রসেসরটিই (কম ইনস্ট্রাকশন লাগার কারণে) বাস্তবে কম সময়ে কাজ শেষ করে।
def execution_time(instruction_count, cpi, clock_rate):
"""আয়রন ল -- সরাসরি সেকেন্ডে ফলাফল দিতে clock_cycle_time = 1/clock_rate ব্যবহার করা হচ্ছে"""
clock_cycle_time = 1 / clock_rate
return instruction_count * cpi * clock_cycle_time
def mips(clock_rate, cpi):
return clock_rate / (cpi * 1_000_000)
# প্রসেসর A -- CISC-ঘরানার: জটিল ইনস্ট্রাকশন, কম ক্লক রেট, বেশি CPI, কিন্তু একই কাজে অনেক কম ইনস্ট্রাকশন লাগে
processor_a = {"name": "প্রসেসর A (CISC-ঘরানার)", "instruction_count": 500_000, "cpi": 2, "clock_rate": 2e9}
# প্রসেসর B -- RISC-ঘরানার: সরল ইনস্ট্রাকশন, বেশি ক্লক রেট, কম CPI, কিন্তু একই কাজে অনেক বেশি ইনস্ট্রাকশন লাগে
processor_b = {"name": "প্রসেসর B (RISC-ঘরানার)", "instruction_count": 3_000_000, "cpi": 1, "clock_rate": 4e9}
for p in (processor_a, processor_b):
et = execution_time(p["instruction_count"], p["cpi"], p["clock_rate"])
m = mips(p["clock_rate"], p["cpi"])
p["execution_time_ms"] = et * 1000
p["mips"] = m
print(f"{p['name']}")
print(f" instruction_count = {p['instruction_count']:,}, CPI = {p['cpi']}, clock_rate = {p['clock_rate']/1e9:.0f} GHz")
print(f" MIPS = {m:,.0f}")
print(f" execution time = {et*1000:.3f} ms")
print()
print("-" * 50)
if processor_a["mips"] < processor_b["mips"] and processor_a["execution_time_ms"] < processor_b["execution_time_ms"]:
print("নিশ্চিত: কম MIPS পাওয়া প্রসেসর A-ই কম সময়ে কাজ শেষ করেছে -- MIPS একা তুলনার জন্য নির্ভরযোগ্য নয়!")
else:
print("এই উদাহরণে counter-intuitive ফলাফল তৈরি হয়নি -- সংখ্যা যাচাই প্রয়োজন।")
৪ · বেঞ্চমার্কিং — বাস্তব সমাধান
MIPS-এর এই সীমাবদ্ধতার বাস্তব সমাধান হলো প্রকৃত, প্রতিনিধিত্বমূলক প্রোগ্রাম/workload-এ সরাসরি এক্সিকিউশন টাইম মাপা — একে বেঞ্চমার্কিং বলা হয়। ইন্ডাস্ট্রিতে স্ট্যান্ডার্ডাইজড বেঞ্চমার্ক স্যুট ব্যবহার করে ভিন্ন প্রসেসর/ISA-র বাস্তব পারফরম্যান্স তুলনা করা হয় — বিমূর্ত প্রতি-ইনস্ট্রাকশন সংখ্যার ওপর নয়, বরং প্রকৃত কাজ কতটা দ্রুত শেষ হয় তার ওপর ভিত্তি করে।
এক্সিকিউশন টাইমই একমাত্র মেট্রিক যা মিথ্যা বলে না — CPI ও MIPS দুটোই দরকারি টুল, কিন্তু বিচ্ছিন্নভাবে দেখলে ভুল সিদ্ধান্তে নিয়ে যেতে পারে। বাস্তব সিদ্ধান্তের জন্য সবসময় প্রকৃত কাজের বেঞ্চমার্ক ফলাফলকেই চূড়ান্ত রেফারেন্স ধরা উচিত।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ কেন MIPS দিয়ে ভিন্ন ISA (যেমন CISC বনাম RISC) তুলনা করা প্রায় অর্থহীন?
কারণ MIPS হিসাব করে না প্রতিটি ইনস্ট্রাকশন কতটা প্রকৃত কাজ করছে। M5/L23 অনুযায়ী একটি CISC ইনস্ট্রাকশন একটি RISC ইনস্ট্রাকশনের চেয়ে অনেক বেশি কাজ করতে পারে — তাই সমান instruction count থাকলেও দুই ISA প্রকৃতপক্ষে ভিন্ন পরিমাণ কাজ শেষ করে ফেলে। MIPS শুধু "প্রতি সেকেন্ডে কতগুলো ইনস্ট্রাকশন" গোনে, প্রতিটি ইনস্ট্রাকশনের "ওজন" নয় — তাই ভিন্ন ISA-র মধ্যে এই সংখ্যা তুলনা করা বিভ্রান্তিকর।
প্র ০২ কোড সেলে প্রসেসর A কম MIPS পেয়েও কম এক্সিকিউশন টাইম পেল কেন — এর মূল কারণ কী?
মূল কারণ হলো instruction count-এর পার্থক্য — প্রসেসর A একই কাজ মাত্র ৫,০০,০০০
ইনস্ট্রাকশনে শেষ করে, প্রসেসর B-এর লাগে ৩০,০০,০০০। এক্সিকিউশন টাইম নির্ভর করে
instruction_count × CPI × clock_cycle_time-এর ওপর, শুধু MIPS-এর ওপর নয়। যেহেতু প্রসেসর
A-কে অনেক কম ইনস্ট্রাকশন এক্সিকিউট করতে হয়, তার মোট সময় কম হয়ে যায়, যদিও তার প্রতি-সেকেন্ড
ইনস্ট্রাকশন-হার (MIPS) কম।
প্র ০৩ বেঞ্চমার্কিং কেন MIPS-এর চেয়ে বেশি নির্ভরযোগ্য বাস্তব পারফরম্যান্স তুলনার উপায়?
বেঞ্চমার্কিং সরাসরি একটি প্রকৃত, প্রতিনিধিত্বমূলক প্রোগ্রাম চালিয়ে প্রকৃত এক্সিকিউশন টাইম মাপে — যা আয়রন ল-এর তিনটি টার্মকেই (instruction count, CPI, clock cycle time) একসাথে হিসাবে নেয়, একটির ওপর বিচ্ছিন্নভাবে নির্ভর করে না। ফলে বেঞ্চমার্ক ফলাফল সরাসরি বাস্তব ব্যবহারকারীর অভিজ্ঞতার সাথে মেলে — যেখানে MIPS-এর মতো বিমূর্ত মেট্রিক প্রায়ই বিভ্রান্তিকর সিদ্ধান্তে নিয়ে যেতে পারে।
অনুশীলন
-
চিন্তা করুন: যদি ক্লক রেট একই রেখে শুধু CPI কমানো হয় (যেমন M7-এর পাইপলাইনিং-এর মাধ্যমে), এক্সিকিউশন টাইমের কী হবে?
আয়রন ল সূত্র অনুযায়ী
ExecutionTime = InstructionCount × CPI × ClockCycleTime— যেহেতুInstructionCountওClockCycleTimeঅপরিবর্তিত, CPI কমলে এক্সিকিউশন টাইমও সরাসরি সমানুপাতিকভাবে কমবে। এটাই ঠিক M7-এর পাইপলাইনিং-এর মূল লক্ষ্য — CPI-কে যতটা সম্ভব ১-এর কাছাকাছি এনে এক্সিকিউশন টাইম কমানো, ক্লক রেট না বাড়িয়েই। -
পরীক্ষা করুন: কোড সেলে যদি
instruction_countদুই প্রসেসরের জন্য একই রাখা হতো, শুধু CPI ও ক্লক রেট আলাদা রাখা হতো — তাহলে কি কম-MIPS প্রসেসর তখনও কম সময় পেতে পারত? (এখনো কোড পরিবর্তন করবেন না।)না, গাণিতিকভাবে অসম্ভব। যেহেতু
ExecutionTime = InstructionCount / (MIPS × 10⁶)— instruction count স্থির থাকলে এক্সিকিউশন টাইম MIPS-এর সাথে বিপরীতভাবে সমানুপাতিক, তাই বেশি MIPS-ই সবসময় কম সময় দেবে। "কম MIPS তবু কম সময়" এই counter-intuitive ফলাফল শুধু তখনই ঘটে যখন দুই প্রসেসরের instruction count আলাদা — ঠিক যেমন এই পাঠের CISC-বনাম-RISC উদাহরণে হয়েছে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ পরবর্তী পাঠ — কেস স্টাডি: x86 বনাম ARM বনাম RISC-V আর্কিটেকচার।
- Operating Systems কোর্স সহোদর কোর্স সেই কোর্সের শিডিউলিং মেট্রিক্স (turnaround, waiting time) সফটওয়্যার-স্তরে; এই CPU-স্তরের মেট্রিক্স হার্ডওয়্যার-স্তরে।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems ও Computer Architecture — সব এক জায়গায়।