11/17 CPU tìm dữ liệu trong RAM Các chương

CPU tìm một byte giữa hàng tỷ byte như thế nào?

Chương trình chỉ nói score. Làm sao CPU tìm đúng dữ liệu đó giữa hàng tỷ byte trong RAM?

Ở bài trước, ta thấy RAM chia hàng tỷ ô nhớ thành nhóm chip, bank, hàng và cột.

Nhưng chương trình không nói:

bank 1, hàng 2, cột 3

Nó chỉ có:

int score = 42;

Vài dòng sau, chương trình cần score.

CPU nói gì với RAM để tìm lại đúng dữ liệu đó?

Câu trả lời là: một địa chỉ.

RAM không biết tên biến

Với người viết chương trình, dữ liệu có những cái tên như:

score
health
playerName

RAM không biết những cái tên đó. Nó chỉ cần biết dữ liệu nằm ở chỗ nào.

Vì vậy từng byte trong bộ nhớ được đánh số:

100 → một byte
101 → một byte
102 → một byte
103 → một byte
...

Mỗi số là một địa chỉ (address).

Một int thường chiếm 4 byte, nên score có thể bắt đầu ở 0x5300 và chiếm:

0x5300
0x5301
0x5302
0x5303

0x… chỉ là cách viết số bằng hệ mười sáu. Địa chỉ thật dài hơn; bài này rút gọn cho dễ nhìn.

Cuối cùng CPU chỉ cần một yêu cầu kiểu:

đọc 4 byte từ 0x5300

Tên score không đi tới RAM.

Nhưng CPU nhìn bộ nhớ như một dãy địa chỉ liền nhau, còn RAM lại chia thành:

nhóm chip → bank → hàng → cột

Ai nối hai cách nhìn đó với nhau?

Memory controller giải mã địa chỉ

Đó là việc của memory controller, mạch điều khiển bộ nhớ nằm ngay trên chip CPU. Nó nhận địa chỉ rồi tách ra xem dữ liệu thuộc bank nào, hàng nào, cột nào:

0x5300

bank 1
hàng 2
cột 3

Yêu cầu đi tiếp qua kênh (channel), đường dây nối CPU với khe cắm RAM.

Nhưng biết hàng và cột vẫn chưa xong. DRAM không chọc thẳng vào một ô rồi lấy đúng byte đó ra.

RAM phải mở cả hàng

Đọc lần lượt 0x5300, 0x5340 rồi 0x9180, và để ý RAM phải làm gì với hàng.

CPU tìm dữ liệu từ một địa chỉ như thế nào?
CPU cần đọc
địa chỉ đã được rút gọn · mỗi bước khoảng 20 ns
CPU
Memory controller
Bank 1
hàng 0
hàng 1
hàng 2
hàng 3
hàng 4
hàng 5
row buffer trống

Đọc lần lượt cả ba địa chỉ. Để ý bước mở hàng.

Với 0x5300, bank mở hàng 2, giữ cả hàng trong row buffer, rồi mới chọn cột.

0x5340 cũng nằm trong hàng 2. Hàng đó còn nguyên trong row buffer nên bank không phải mở lại, chỉ chọn cột khác. Đây gọi là row hit.

0x9180 nằm ở hàng 5. Bank phải đóng hàng (precharge) hàng 2, đưa các đường bit về mức chờ, rồi mới mở được hàng mới.

Vì vậy hai lần đọc cùng lấy vài byte mà tốn công khác hẳn nhau.

DRAM không nhặt riêng một byte từ lưới ô nhớ. Nó mở cả một hàng vào row buffer rồi chọn phần cần đọc.

Nhưng dù gặp row hit, đi tới RAM vẫn là một chuyến khá xa:

CPU

memory controller

kênh

thanh RAM → bank → row buffer

quay về CPU

Suốt chuyến đó, CPU đứng chờ.

Vì vậy CPU có cache

Ngay trong chip CPU có những vùng nhớ nhỏ làm bằng SRAM, gọi là cache:

nhân CPU

L1

L2

L3

RAM

Cần một địa chỉ, CPU hỏi cache trước. Có bản sao thì dùng luôn. Không có, gọi là cache miss, yêu cầu mới đi tới memory controller rồi tới thanh RAM.

Khi đã phải đi cả chuyến, RAM không gửi về đúng 4 byte của score. Nó gửi về cả một khối gọi là cache line, thường gặp là 64 byte:

CPU cần

[ ][ ][ ][ ][X][ ][ ][ ]

cache nhận về
[████████████████████████]
         64 byte

Mất công đi cả đường rồi thì mang thêm một ít gần như không tốn gì, mà byte bên cạnh thường cũng sắp được dùng tới.

Với RAM, một biến cuối cùng chỉ là một địa chỉ. Địa chỉ được đổi thành bank, hàng và cột; DRAM mở cả hàng để đọc; còn cache giữ bản sao gần CPU để khỏi đi lại chuyến đó.

Cache nhanh, nhưng nhỏ. RAM lớn hơn, nhưng chậm hơn. SSD còn lớn và rẻ hơn nữa, nhưng chậm hơn rất nhiều.

Vậy sao phải chia bộ nhớ thành nhiều lớp? Sao không làm một loại bộ nhớ vừa nhanh như cache, vừa lớn như RAM, vừa rẻ như SSD?