আগের আর্টিকেলে দেখা গেছে — ২ আর ৩ কীভাবে যোগ হয়ে ৫ হয়। কিন্তু পুরো কাহিনী শেষ হয়নি। একটা প্রশ্নের উত্তর দেয়া বাকি ছিল।
CPU জানল কীভাবে যে এই মুহূর্তে তাকে যোগ করতে হবে? বিয়োগ না, গুণ না — যোগ। আর এই দুইটা register-এর ডেটা নিতে হবে, বাকিগুলো না। এই instruction তাকে কে দিল?
আজকের গল্পটা ঠিক এখান থেকেই শুরু।
আমরা এখনও সিলিকনের সেই ছোট্ট শহরের ভেতরেই আছি, যেখানে ALU, Register, Data Bus আর Clock একসাথে কাজ করছে। তবে আজকে আমাদের ফোকাস পার্টসগুলোর ওপর নয়, বরং সময়ের ওপর। আগের আর্টিকেলটি ছিল একটি স্থিরচিত্র — সিলিকনের ভেতরে কী কী যন্ত্রাংশ সাজানো থাকে তার বিবরণ। আর এই আর্টিকেলটি হবে একটি চলমান ভিডিও। এক মুহূর্ত থেকে আরেক মুহূর্তে সিপিইউ-র ভেতরে ঠিক কী ঘটে, কীভাবে একটি ইন্সট্রাকশন মেমোরি থেকে বেরিয়ে এসে প্রসেসরের ভেতরে ঢোকে, নিজের অর্থ প্রকাশ করে এবং একটি বাস্তব কাজে পরিণত হয় — আজ আমরা সেটাই দেখব।
instruction-ও শুধু bit
আমরা যখন কোনো কোড লিখি, তখন আমাদের মনে হয় "কোড" আর "ডেটা" সম্পূর্ণ ভিন্ন দুটি জিনিস। কিন্তু সিলিকনের একদম গভীরে নেমে দেখলে দেখা যাবে, instruction আর ডেটা — দুটোই memory-তে ঠিক একই রকম দেখতে। শুধু voltage-এর pattern। ০ আর ১-এর একটা sequence।
তার মানে, "যোগ করো" — এই instruction-টাও শেষ পর্যন্ত একটা bit sequence। "লাল pixel" — সেটাও একটা bit sequence। "42" সংখ্যাটা memory-তে যেভাবে বসে থাকে, "ADD" instruction-ও ঠিক সেভাবেই বসে থাকে। শুধু voltage। memory চিনে না কোনটা instruction, কোনটা ডেটা। memory-র কাছে সবই একই ধরনের bit।
এটা প্রথম আর্টিকেলের সেই কথারই আরেকটা রূপ — CPU is blind, software gives meaning। এখানেও তেমনই। একই bit sequence, context ভেদে instruction হতে পারে, ডেটাও হতে পারে।
তাহলে CPU একটা bit sequence-কে "instruction" হিসেবে treat করবে কেন? এই প্রশ্নে আসছি একটু পরে। আগে দেখা যাক, একটা instruction আসলে দেখতে কেমন হয়।
একটা instruction-এর ব্যবচ্ছেদ
ধরুন CPU-কে বলতে চাই: "Register A আর Register B যোগ করে ফলাফল Register C-তে রাখো।" এই পুরো বাক্যটি মেমোরিতে কীভাবে সাজানো থাকে?
বাস্তব প্রসেসরে একটি instruction ৩২ বা ৬৪ বিটের হয়ে থাকে। তবে বোঝার সুবিধার জন্য আমরা ধরে নিই আমাদের instruction ১৩ বিটের একটি নির্দিষ্ট ফরম্যাট বা কাঠামো মেনে চলে:
0001 | 001 | 010 | 011 Opcode | Reg A | Reg B | Reg C
একটি স্ট্যান্ডার্ড instruction প্রধানত দুটি অংশে বিভক্ত থাকে:
- Opcode (Operation Code): instruction-এর প্রথম অংশ, যা CPU-কে বলে দেয় কী কাজ করতে হবে। আমাদের কাল্পনিক ডিজাইনে, প্রথম ৪টি বিট হলো Opcode। প্রসেসরের হার্ডওয়্যারে ফিক্সড করা থাকে যে 0001 মানে ADD (যোগ), 0010 মানে SUB (বিয়োগ), আর 0011 মানে LOAD।
- Operand: instruction-এর পরের অংশগুলো, যা বলে দেয় কার ওপর অপারেশনটি চালানো হবে। এখানে বাকি বিটগুলো হলো রেজিস্টারগুলোর ৩-বিটের বাইনারি অ্যাড্রেস বা ঠিকানা (যেমন: Register A = 001, B = 010, C = 011)।
CPU যখন মেমোরি থেকে এই ১৩টি বিট নিজের ভেতরে টেনে নেয়, সে তার Control Unit-এর decoder দিয়ে প্রথম ৪ বিট কেটে আলাদা করে এবং মুহূর্তে বুঝে যায় — "আমাকে এখন যোগ করতে হবে।" এরপর সে পরের বিটগুলো দেখে চিনে নেয় ডেটার উৎস এবং গন্তব্য। নিচের যন্ত্রে opcode আর operand পাল্টে দেখুন — বিটগুলো কীভাবে বদলায়:
Program Counter: কার পালা এখন?
মেমোরির কাছে যদি instruction আর ডেটা হুবহু একই রকম দেখতে হয়, তাহলে CPU কীভাবে বোঝে যে মেমোরির কোন অংশটি একটি কমান্ড আর কোন অংশটি সাধারণ ডেটা? আর memory-তে এত এত instruction — একটার পর একটা কীভাবে ঠিক ক্রমে execute হবে?
এই সমস্যার সমাধানের জন্য CPU-র ভেতরে একটা বিশেষ register থাকে — যার নাম Program Counter (সংক্ষেপে PC)। কোনো কোনো আর্কিটেকচারে একে Instruction Pointer-ও বলে।
এই PC-র কাজ একটাই — এই মুহূর্তে memory-র কোন address থেকে পরের instruction পড়তে হবে, সেই address-টা ধরে রাখা।
কম্পিউটার যখন কোনো প্রোগ্রাম চালু করে, তখন অপারেটিং সিস্টেম PC-র ভেতরে ওই প্রোগ্রামের ঠিক প্রথম instruction-এর address বসিয়ে দেয়। ব্যস, প্রসেসরের ইঞ্জিন চালু হয়ে গেল। সিপিইউ চোখ বন্ধ করে PC-র নির্দেশ করা address-এ যায় এবং ওখান থেকে যে bit sequence পায়, সেটিকে instruction হিসেবে ধরে নেয়। কাজ শেষে PC নিজে থেকে এক ধাপ বাড়ে — পরের instruction-এর দিকে ইঙ্গিত করে।
সহজ কথায়, "কোনটা instruction, কোনটা data" — এই পার্থক্যটা memory-তে নেই। কোথাও লেখা থাকে না। পার্থক্যটা তৈরি হয় PC-র মাধ্যমে। PC প্রসেসরের কাজের সময়ে মেমোরির যে অংশকে ইঙ্গিত করে, ভেতরের সার্কিটগুলো সেই bit-গুলোকে instruction হিসেবে treat করে। বাকি অংশগুলো সাধারণ data হিসেবে মেমোরিতে পড়ে থাকে।
এবার সব উপাদান হাতে আছে। Instruction memory-তে বসে আছে। PC ঠিক জানে কোনটা এখন পড়তে হবে। এবার actual cycle-টা কীভাবে ঘটে?
Fetch-Decode-Execute: কম্পিউটিং-এর মৌলিক রিদম
একটি instruction মেমোরি থেকে এসে পুরোপুরি সম্পন্ন হওয়া পর্যন্ত পুরো প্রক্রিয়াটি তিনটি প্রধান ধাপে বিভক্ত। একে বলা হয় Instruction Cycle বা প্রসেসরের মৌলিক লাইফ-সাইকেল। ধাপ তিনটি হলো: Fetch, Decode, এবং Execute।
১. Fetch (instruction টেনে আনা)
এই প্রথম ধাপে কোনো মগজ খাটানোর কাজ নেই, এটি স্রেফ ট্রান্সপোর্টেশন বা পরিবহনের ধাপ।
CPU-র Control Unit প্রথমে PC-তে থাকা মেমোরি address-টি পড়ে নেয়। এরপর প্রসেসরের Address Bus-এর মাধ্যমে সেই ঠিকানাটি র্যামে (RAM) পাঠানো হয়। মেমোরি সেই নির্দিষ্ট address-টি খুঁজে বের করে তার ভেতরে থাকা ১৩টি bit-কে Data Bus-এর তার দিয়ে CPU-র কাছে ফেরত পাঠায়। এই bit-গুলো এসে প্রসেসরের ভেতরের আরেকটি বিশেষ register-এ জমা হয়, যার নাম Instruction Register (সংক্ষেপে IR)।
ঠিক এই মুহূর্তেই, PC মেমোরির পরবর্তী instruction-টি ধরার জন্য নিজের ভেতরের address value এক ধাপ বাড়িয়ে নেয় (increment করে)।
২. Decode (instruction-এর অর্থ উদ্ধার)
Instruction-এর bit-গুলো এখন প্রসেসরের ভেতরে, IR register-এ এসে বসে আছে। কিন্তু প্রসেসরের ভেতরের হার্ডওয়্যার এখনো জানে না এই ভোল্টেজের হিজিবিজি প্যাটার্নটি আসলে কী করতে বলছে।
এই ধাপে চার্জ নেয় প্রসেসরের আসল ডিরেক্টর — Control Unit (সংক্ষেপে CU)। Control Unit নিজে কোনো গাণিতিক হিসাব করে না, সে মূলত অন্য পার্টসগুলোকে পরিচালনা করে।
CU প্রথমে IR-এ থাকা instruction-এর প্রথম ৪টি bit (Opcode) কেটে নেয়। এরপর একটি অভ্যন্তরীণ ডিকোডার সার্কিটের মাধ্যমে সেই ৪টি bit-কে অ্যানালাইসিস করে। বিট প্যাটার্ন যদি হয় 0001 (ADD), তবে Control Unit মুহূর্তে বুঝে যায় এখন যোগ করতে হবে। সে সাথে সাথে পুরো চিপের ভেতরে থাকা বিভিন্ন control wire বা নিয়ন্ত্রণ তারের ভোল্টেজ বদলে দেয়:
- ALU-কে বলে: "তোমার ভেতরের যোগ করার সার্কিট (Add Mode) অন করো।"
- Multiplexer-কে বলে: "রাস্তা খুলে দাও, যেন Register A আর Register B-র data সরাসরি ALU-র ইনপুটে চলে যায়।"
- Destination Decoder-কে বলে: "তুমি তৈরি থাকো, ALU-র আউটপুট কিন্তু সরাসরি Register C-তে যাবে।"
৩. Execute (বাস্তব রূপায়ণ)
সব সিগন্যাল রেডি, ট্রাফিক লাইট গ্রিন। এবার শুরু হয় আসল অ্যাকশন।
ক্লকের টাইমিং সিগন্যাল অনুযায়ী Register A-এর value (২) এবং Register B-এর value (৩) মাল্টিপ্লেক্সার পার হয়ে ALU-র ফুল-অ্যাডার সার্কিটে প্রবেশ করে। লজিক গেটের মধ্য দিয়ে কারেন্ট প্রবাহিত হয়ে আউটপুট লাইনে ৫ (0101) তৈরি হয়। এই নতুন ভোল্টেজ প্যাটার্নটি অভ্যন্তরীণ data বাসের তার বেয়ে সরাসরি Register C-তে গিয়ে পৌঁছায়। ক্লকের পরবর্তী ট্রানজিশনে সেই ৫ value-টি Register C-র ফ্লিপ-ফ্লপগুলোতে পার্মানেন্টলি ল্যাচ বা সেভ হয়ে যায়।
নিচের যন্ত্রে পুরো সাইকেলটা নিজে একবার চালিয়ে দেখতে পারেন:
অবিরাম হার্টবিট
একটি instruction-এর গল্প শেষ হলো। কিন্তু CPU-র ডিকশনারিতে "বিশ্রাম" বলে কোনো শব্দ নেই।
ক্লকের পরের পালস আসার সাথে সাথেই CPU আবার প্রথম ধাপ অর্থাৎ Fetch-এ ফেরত চলে যায়। PC যেহেতু আগের ধাপেই এক ধাপ বেড়ে মেমোরির পরের address-টি ধরে রেখেছে, তাই CPU এবার মেমোরির নতুন ঠিকানা থেকে পরের instruction-টি টেনে আনে, সেটিকে ডিকোড করে এবং execute করে।
এই চক্রটি কম্পিউটারে অবিরাম চলতে থাকে: Fetch → Decode → Execute → Fetch... যতক্ষণ না কম্পিউটারটি বন্ধ করা হচ্ছে। একটি 3.0 GHz ক্লক স্পিডের প্রসেসরে প্রতি সেকেন্ডে এই সাইকেলটি কোটি কোটি বার সম্পন্ন হয়।
আপনি যখন স্ক্রিনে এই আর্টিকেলটি স্ক্রল করছেন, মাউস নড়াচ্ছেন, ব্যাকগ্রাউন্ডে গান শুনছেন কিংবা কোনো AI চ্যাটবটের সাথে কথা বলছেন — তার পেছনে রয়েছে এই তিনটি ধাপের কোটি কোটি বারের অবিরাম পুনরাবৃত্তি। সফটওয়্যারের যত জটিল লেয়ারই আমরা উপরে তৈরি করি না কেন, একদম নিচে সিলিকনের বাস্তবতায় সবকিছু এই সাধারণ রিদমে এসে থিতু হয়।
পুরো গল্পটা একবার
এবার সেই যোগ করার instruction-এর পুরো যাত্রা একবার চালিয়ে দেখা যাক।
কোথাও memory-তে একটা bit sequence বসে আছে — 0001 001 010 011। কেউ জানে না এটা কী। শুধু voltage-এর একটা pattern।
কিন্তু PC-তে সেই bit sequence-এর address রাখা আছে। Clock একটা tick দিল। Fetch শুরু। CPU সেই address-এ গেল, bit-গুলো তুলে আনল, IR-এ বসিয়ে দিল। এই মুহূর্তে PC নিজে থেকে বেড়ে গেল — এখন পরের address-এ point করছে।
Clock আরেকটা tick দিল। Decode শুরু। Control Unit IR-এর প্রথম ৪ bit দেখে বলল — "ADD।" সঙ্গে সঙ্গে control signal ছড়িয়ে পড়ল CPU-র বিভিন্ন অংশে। ALU যোগ mode-এ গেল। Mux Register A আর Register B বেছে নিল। Decoder Register C-কে প্রস্তুত করল।
Clock আরেকটা tick দিল — এবার Execute। ২ আর ৩ চলে গেল ALU-র দিকে, ৫ বেরিয়ে এল, Register C-তে বসে গেল।
তিনটা ধাপে একটা instruction সম্পন্ন। CPU-র কাছে এটা মাত্র একটা হার্টবিট। আর এই মুহূর্তেই — কোনো বিরাম নেই — PC পরের instruction-এর দিকে ইঙ্গিত করছে। সেটাও fetch হবে। Decode হবে। Execute হবে।
আপনার React app। YouTube video। Photoshop। AI chatbot। সব — literally সব — এই তিনটা stage-এর অবিরাম repetition। উপরের সব software layer একসাথে যা করে, সেটা শেষে এই তিনটা stage-এই এসে দাঁড়ায়।
সবকিছু এত সরল নয়: Pipelining
বোঝার সুবিধার জন্য আমরা এখানে data ফ্লো-কে এমনভাবে দেখিয়েছি যেন একটি instruction-এর তিন ধাপ পুরোপুরি শেষ হওয়ার পর পরবর্তী instruction-এর কাজ শুরু হয়। একে বলে Single-Cycle Architecture।
কিন্তু বাস্তব আধুনিক প্রসেসরগুলো এভাবে অলস বসে থাকে না। সেখানে ব্যবহৃত হয় Pipelining মেকানিজম। একটি কারখানার অ্যাসেম্বলি লাইনের কথা ভাবুন — যেখানে একই সময়ে একটি গাড়িতে পেইন্ট করা হচ্ছে, তার পেছনের গাড়িতে চাকা লাগানো হচ্ছে, আর তারও পেছনের গাড়িটির বডি জোড়া দেওয়া হচ্ছে।
CPU-ও ঠিক এই কাজটিই করে। যখন একটি instruction Execute ধাপে থাকে, তখন তার ঠিক পরের instruction-টি প্রসেসরের Decode ধাপে প্রসেস হতে থাকে, এবং একই সময়ে মেমোরি থেকে তারও পরের instruction-টি Fetch হতে থাকে। নিচের যন্ত্রে দুই mode-এর তফাতটা tick করে দেখুন:
- কোড ও data-র অভিন্নতা: মেমোরির কাছে কোড আর data-র গঠনে কোনো পার্থক্য নেই, দুটোই স্রেফ ভোল্টেজ বা bit সিকোয়েন্স।
- পার্থক্য গড়ে দেয় Program Counter: PC মেমোরির যে address-কে নির্দেশ করে, CPU সেই bit-গুলোকেই instruction হিসেবে treat করে।
- Control Unit হলো ডিরেক্টর: CU কোনো ম্যাথ করে না, সে instruction-এর opcode পড়ে ডিকোডারের মাধ্যমে সঠিক কন্ট্রোল সিগন্যাল জেনারেট করে বাকি পার্টসগুলোকে পরিচালনা করে।
- কম্পিউটিং-এর রিদম: প্রতিটি প্রসেসরের মূল প্রাণশক্তি লুকিয়ে আছে Fetch-Decode-Execute সাইকেলের অবিরাম লুপের মাঝে।