সালটা ২০১৭। আমি আমার জীবনের সবচেয়ে বোল্ড সিদ্ধান্তটা নিয়ে ফেললাম: ক্যারিয়ার শিফট করে ঢুকে পড়লাম সফটওয়্যার ইন্ডাস্ট্রিতে।

আমি তখন একজন নন-CSE ব্যাকগ্রাউন্ডের মানুষ। পড়াশোনা করেছি গার্মেন্টস ডিজাইন অ্যান্ড প্যাটার্ন মেকিং ইঞ্জিনিয়ারিং নিয়ে। কোডিং শিখতে শিখতে অনেকটা ভালোবাসাও জন্মে গিয়েছিল, কিন্তু একটা জিনিস আমাকে বারবার ভাবাতো: "আমি কোড তো লিখছি, কিন্তু কম্পিউটার ভিতরে বসে এগুলো আসলে কীভাবে চালায়?"

তখন শুধু code লিখতে পারতাম, কিন্তু আমার লেখা program computer-এর ভিতরে কীভাবে কাজ করে সেটা বুঝতাম না। CPU, memory, OS এই জিনিসগুলো বুঝতে অনেকদিন লেগেছে; ধীরে ধীরে জট খুলতে শুরু করে।

আজকে সেই অভিজ্ঞতা থেকে খুব সহজ করে বোঝানোর চেষ্টা করব CPU-র ভিতরে আসলে কী হয়। বাংলায় সহজ ভাষায় ও গভীরভাবে ব্যাখ্যা করা রিসোর্স খুব কম, তাই এই আর্টিকেলটা লেখা, যাতে আপনার মতো আরেকজন আগ্রহী মানুষ সহজ ভাষায় এই জটিল বিষয়গুলো বুঝতে পারেন।

শুরুতে CPU নিয়ে দুটো কথা

CPU মানে Central Processing Unit। একে computer এর "brain" বলা হয়, কিন্তু আসলে এটা brain এর মতো চিন্তা করে না, বরং খুব দ্রুত গতিতে simple mathematical operations করে। আমরা যে program লিখি, সেটা শেষ পর্যন্ত CPU এর কাছে গিয়ে পৌঁছায় 0 আর 1 হিসেবে, যাকে বলি machine code।

CPU এর প্রধান অংশগুলো

১. Control Unit (CU)

এটা হলো CPU এর "traffic controller"। Program এর instruction গুলো কোন order এ execute হবে, কোন data কোথায় পাঠাতে হবে, এসব control করে CU।

Example: মনে করেন আপনি একটা recipe follow করছেন। CU হলো সেই person যে বলছে "প্রথমে চাল ধুয়ে নাও, তারপর পানি দাও, তারপর চুলায় দাও"।

২. Arithmetic Logic Unit (ALU)

এখানে সব mathematical calculations হয়। Addition, subtraction, multiplication, division এবং logical operations (AND, OR, NOT) সব এখানে হয়।

Example: যদি আপনি লিখেন var result int = 5 + 3{:go} তাহলে এই addition টা ALU তে হবে।

৩. Registers

এগুলো হলো CPU এর সবচেয়ে fast memory। খুব small amount এর data temporarily store করে রাখে। CPU এই মুহূর্তে যে data বা instruction নিয়ে কাজ করছে সেটা register-এ থাকে, তাই ALU কোনো দেরি ছাড়াই data access করতে পারে। যেমন:

  • Accumulator: Calculation এর result store করে
  • Program Counter (PC): পরবর্তী instruction এর address রাখে
  • Instruction Register (IR): Current instruction রাখে

৪. Cache Memory

RAM থেকে data আনতে time লাগে। তাই frequently used data cache এ রাখা হয় যাতে দ্রুত access করা যায়।

  • L1 Cache: সবচেয়ে fast, CPU এর সাথে attached
  • L2 Cache: একটু slow কিন্তু বড়
  • L3 Cache: সবচেয়ে বড়, কিন্তু তিনটার মধ্যে ধীরতম

Program Execution Process: Step by Step

এখন একটা simple calculator program দিয়ে দেখাবো কীভাবে step by step execution হয়:

package main

import "fmt"

func main() {
    var a int = 10
    var b int = 5
    var sum int = a + b
    fmt.Printf("Sum: %d\n", sum)
}

আগে নিজে চালিয়ে দেখুন

নিচের visualizer-এ এই program-টাই ধাপে ধাপে execute হয়। Play চাপুন, বাঁয়ে CPU-র register-গুলো আর ডানে memory-র ঘরগুলো কীভাবে বদলায় সেটা লক্ষ্য করুন। যেকোনো memory cell-এ click করলে তার address আর ব্যাখ্যা পাবেন।

সব step পুরোপুরি না বুঝলেও সমস্যা নেই। এবার ধাপে ধাপে দেখি ভেতরে আসলে কী হলো।

Step 1: Program Loading (Storage থেকে Memory তে)

যখন আপনি program run করেন:

  1. Hard disk/SSD থেকে compiled program (executable file) RAM এ load হয়
  2. Operating System একটা process create করে
  3. Program এর instructions এবং data আলাদা আলাদা memory segment এ রাখা হয়
 Hard Disk → RAM
 [program.exe] → [Code Segment | Data Segment | Stack | Heap]

Step 2: Fetch Cycle শুরু

  1. Program Counter (PC) এ first instruction এর address থাকে
  2. CPU সেই address থেকে instruction fetch করে
  3. Instruction Instruction Register (IR) এ store হয়
 PC: 0x1000 → Memory[0x1000] → IR: "var a int = 10"

আসলে IR-এ থাকে machine instruction (binary), source code-এর লাইন নয়। বোঝার সুবিধার জন্য এখানে source line-টাই দেখাচ্ছি।

Step 3: Decode Phase

Control Unit instruction decode করে বুঝে:

  • এটা একটা variable declaration
  • Value 10 কে register এ store করতে হবে
  • Memory তে space allocate করতে হবে

Step 4: Execute Phase: Line by Line

Line 1: var a int = 10{:go}

 1. Memory তে 8 bytes space allocate করে → address: 0x2000 (64-bit সিস্টেমে Go-র int হয় 64-bit)
 2. Value 10 কে register এ load → R1 = 10
 3. R1 এর value memory তে store → Memory[0x2000] = 10

Line 2: var b int = 5{:go}

 1. Memory তে আরো 8 bytes space → address: 0x2008  
 2. Value 5 কে register এ load → R2 = 5
 3. Memory তে store → Memory[0x2008] = 5

Line 3: var sum int = a + b{:go}

 1. Variable 'a' এর value register এ load → R1 = Memory[0x2000] = 10
 2. Variable 'b' এর value register এ load → R2 = Memory[0x2008] = 5
 3. ALU তে addition operation → R3 = R1 + R2 = 15
 4. Result কে memory তে store → Memory[0x2010] = 15

Visual Representation

প্রতিটা অংশে hover করুন (বা keyboard এ Tab চাপুন): কোন অংশ কী কাজ করে দেখতে পাবেন।

CPUCentral Processing Unit: fetch-decode-execute cycle এ instruction চালায়। ভিতরের যেকোনো অংশে hover করুন।
RegistersCPU এর সবচেয়ে দ্রুত storage — nanosecond access। ALU শুধু register এর data নিয়েই কাজ করতে পারে।
R110General-purpose register। Memory[0x2000] থেকে a এর মান load হয়েছে।R25Memory[0x2008] থেকে b এর মান load হয়েছে।R315ALU এর ফলাফল: R1 + R2। পরে Memory[0x2010] এ store হবে।
ALUArithmetic Logic Unit: যোগ-বিয়োগ-গুণ-ভাগ আর logical operation (AND, OR, NOT) সব এখানে হয়।
[+] [−] [×] [÷]
Control UnitCPU এর traffic controller: instruction decode করে ঠিক করে কোন data কোথায় যাবে, কোন operation হবে।
PC0x1004Program Counter: পরবর্তী instruction এর memory অ্যাড্রেস। প্রতি instruction শেষে ইনক্রিমেন্ট হয়।IRadd R1,R2Instruction Register: এই মুহূর্তে যে instruction execute হচ্ছে সেটা এখানে থাকে।
busSystem bus: CPU আর memory এর মধ্যে data, address আর control signal যাতায়াত করে।
Cacheএটা ছোট কিন্তু খুব দ্রুত memory। CPU প্রথমে এখানেই data খোঁজে, তারপর প্রয়োজন হলে RAM-এ যায়
L1~1nsসবচেয়ে ছোট, সবচেয়ে দ্রুত — CPU core এর ভিতরেই থাকে। প্রথমে এখানে খোঁজা হয়।L2~4nsL1 miss হলে এখানে। একটু বড়, একটু ধীর।L3~15nsসব core মিলে share করে। এখানেও না পেলে RAM এ যেতে হয় (~100ns)।
busCache miss হলে memory controller RAM থেকে data আনে — cache hit এর চেয়ে ~২৫ গুণ স্লো
RAMMain memory: চলমান program এর সব data আর instruction এখানে থাকে। Computer বন্ধ হলে বা power চলে গেলে এগুলো মুছে যায়
0x200010 (a)Variable a — stack এ ৮ bytes (Go তে int 64-bit)।0x20085 (b)Variable b — a এর ঠিক পরের ৮ bytes।0x201015 (sum)sum — ALU এর ফলাফল R3 থেকে store হয়েছে।

Step 5: fmt.Printf Function Call

fmt.Printf("Sum: %d\n", sum)

এটা একটু complex:

  1. Stack এ sum (function parameters) push হয়
  2. Function Call হয় → CPU jumps to fmt.Printf
  3. Output print করে → “Sum: 15”
  4. Stack clean up হয়

Go 1.17 থেকে argument আসলে আগে register দিয়ে pass হয়; stack-এ push করা দেখাচ্ছি ধারণাটা সহজ রাখতে।

CPU এর Internal Process

1. PUSH sum → Stack: [15]
2. CALL fmt.Printf → PC jumps to fmt.Printf address
3. fmt.Printf executes → Screen output: "Sum: 15"
4. POP stack    → Stack: []
5. RETURN       → PC returns to main

Cache এর ভূমিকা

আমাদের program execute করার সময়:

  1. প্রথমে L1 cache check করে data আছে কিনা
  2. না থাকলে L2, তারপর L3 check করে
  3. কোথাও না থাকলে RAM থেকে fetch করে
  4. Frequently used data cache এ রেখে দেয়
CPU Request: "a এর value দাও"
L1 Cache: "নেই"
L2 Cache: "নেই" 
RAM: "আছে, 10" → Cache এ copy → CPU কে দেয়

Program Counter এর Journey

Program Counter (PC) continuously track করে কোন instruction execute হবে:

Initial: PC = 0x1000 (var a int = 10)
After:   PC = 0x1004 (var b int = 5)  
After:   PC = 0x1008 (var sum int = a + b)
After:   PC = 0x100C (fmt.Printf call)
After:   PC = 0x1010 (function end)

Memory Layout এর চিত্র

High Address

MEMORY

Stack

grows

Local variables, function calls

Heap

grows

Dynamic allocation

Data

Global variables

Code

Program instructions

Low Address

কেন এত Complex Process?

আপনি হয়তো ভাবছেন এত simple একটা program এর জন্য এতো steps কেন? কারণ:

  1. Security: Memory protection, unauthorized access prevent করা
  2. Efficiency: Multiple programs same time run করা
  3. Optimization: Cache ব্যবহার করে speed বাড়ানো
  4. Error Handling: Program crash হলে পুরো system যাতে crash না হয়

Performance কোথায় আটকায়

CPU এর speed measure করা হয় Clock Speed দিয়ে (GHz এ)। Modern CPU প্রতি second এ billions instructions execute করতে পারে। কিন্তু:

  • Memory access: RAM থেকে data আনতে time লাগে
  • Cache miss: Data cache এ না থাকলে slow হয়
  • Branch prediction: if-else statements এর জন্য CPU guess করে

Practical Tips

Programming করার সময় যেসব বিষয় মাথায় রাখবেন:

  1. Local variables use করবেন: cache friendly
  2. Loop optimization করবেন: branch prediction এর জন্য
  3. Data structures choose করবেন carefully: memory access pattern এর জন্য

শেষ কথা

এই পুরো process টা milliseconds এর fraction এ হয়ে যায়। কিন্তু পর্দার আড়ালে CPU, memory, cache সবার coordination এ আমাদের program run হয়।

যখন এসব জানতাম না, তখন শুধু code লিখতাম। এখন internal process টা জানার পর কোড লেখার সময় ভেতরে কী হচ্ছে সেটা চোখের সামনে দেখতে পাই।

লেখাটা কাজে লাগলে পরিচিত কাউকে পাঠাতে পারেন। আর কোনো ভুল চোখে পড়লে জানাবেন, শুধরে নেব।

References