Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 5

3.

3 virtual memory

**Dịch sang tiếng Việt:**

Trong khi các thanh ghi cơ sở và giới hạn có thể được sử dụng để tạo ra sự trừu tượng của không gian
địa chỉ, vẫn còn một vấn đề khác cần phải giải quyết: quản lý phần mềm thừa. Trong khi kích thước bộ
nhớ đang tăng lên nhanh chóng, kích thước phần mềm còn tăng nhanh hơn nhiều. Vào những năm
1980, nhiều trường đại học đã chạy hệ thống chia sẻ thời gian với hàng chục người dùng (hơn kém hài
lòng) chạy đồng thời trên một máy VAX 4-MB. Bây giờ Microsoft khuyến nghị có ít nhất 2 GB cho
Windows 8 64-bit. Xu hướng hướng tới đa phương tiện còn đặt nhiều yêu cầu hơn nữa lên bộ nhớ. Kết
quả của những phát triển này là cần phải chạy các chương trình quá lớn để có thể vừa trong bộ nhớ, và
chắc chắn cần có các hệ thống có thể hỗ trợ nhiều chương trình chạy đồng thời, mỗi chương trình phù
hợp với bộ nhớ nhưng tất cả chúng cộng lại vượt quá bộ nhớ. Hoán đổi không phải là một lựa chọn hấp
dẫn, vì một đĩa SATA điển hình có tốc độ truyền tải tối đa vài trăm MB/giây, có nghĩa là mất vài giây để
hoán đổi một chương trình 1-GB và cũng mất cùng thời gian để hoán đổi vào một chương trình 1-GB.

Vấn đề của các chương trình lớn hơn bộ nhớ đã tồn tại từ khi bắt đầu có máy tính, mặc dù trong các lĩnh
vực hạn chế như khoa học và kỹ thuật (mô phỏng sự tạo ra của vũ trụ hoặc thậm chí mô phỏng một
chiếc máy bay mới cần rất nhiều bộ nhớ). Một giải pháp được áp dụng vào những năm 1960 là chia
chương trình thành những mảnh nhỏ, gọi là các lớp phủ (overlay). Khi một chương trình bắt đầu, tất cả
những gì được tải vào bộ nhớ là trình quản lý lớp phủ, và ngay lập tức tải và chạy lớp phủ 0. Khi hoàn
thành, nó sẽ yêu cầu trình quản lý lớp phủ tải lớp phủ 1, hoặc là trên lớp phủ 0 trong bộ nhớ (nếu có đủ
không gian) hoặc đè lên lớp phủ 0 (nếu không có đủ không gian). Một số hệ thống lớp phủ rất phức tạp,
cho phép nhiều lớp phủ trong bộ nhớ cùng một lúc. Các lớp phủ được lưu trữ trên đĩa và được hoán đổi
vào và ra khỏi bộ nhớ bởi trình quản lý lớp phủ.

Mặc dù công việc thực tế của việc hoán đổi các lớp phủ vào và ra được thực hiện bởi hệ điều hành, công
việc chia chương trình thành các mảnh nhỏ phải được thực hiện thủ công bởi lập trình viên. Chia các
chương trình lớn thành các mảnh nhỏ, có tính mô-đun là tốn thời gian, nhàm chán, và dễ mắc lỗi. Rất ít
lập trình viên giỏi về việc này. Không lâu sau đó, có người nghĩ ra một cách để chuyển toàn bộ công việc
này cho máy tính. Phương pháp được phát minh (Fotheringham, 1961) đã trở thành cái mà chúng ta biết
đến ngày nay là bộ nhớ ảo (virtual memory). Ý tưởng cơ bản đằng sau bộ nhớ ảo là mỗi chương trình có
không gian địa chỉ riêng, được chia thành các mảnh nhỏ gọi là các trang (pages). Mỗi trang là một dải địa
chỉ liên tục. Các trang này được ánh xạ vào bộ nhớ vật lý, nhưng không phải tất cả các trang đều phải có
trong bộ nhớ vật lý cùng một lúc để chạy chương trình. Khi chương trình tham chiếu đến một phần của
không gian địa chỉ của nó mà đang ở trong bộ nhớ vật lý, phần cứng thực hiện việc ánh xạ cần thiết ngay
lập tức. Khi chương trình tham chiếu đến một phần của không gian địa chỉ mà không có trong bộ nhớ vật
lý, hệ điều hành sẽ được báo hiệu để lấy phần thiếu và thực hiện lại lệnh bị lỗi.
Theo một cách nào đó, bộ nhớ ảo là sự tổng quát hóa của ý tưởng về thanh ghi cơ sở và giới hạn. Bộ vi
xử lý 8088 có các thanh ghi cơ sở riêng biệt (nhưng không có thanh ghi giới hạn) cho văn bản và dữ liệu.
Với bộ nhớ ảo, thay vì chỉ có sự chuyển dịch riêng biệt cho các đoạn văn bản và dữ liệu, toàn bộ không
gian địa chỉ có thể được ánh xạ vào bộ nhớ vật lý trong các đơn vị khá nhỏ. Chúng tôi sẽ trình bày cách
thức bộ nhớ ảo được triển khai dưới đây. Bộ nhớ ảo hoạt động tốt trong một hệ thống đa chương trình,
với các mảnh và phần của nhiều chương trình trong bộ nhớ cùng một lúc. Khi một chương trình đang
chờ các phần của nó được đọc vào, CPU có thể được trao cho một quá trình khác.

3.3.1 Paging

Hầu hết các hệ thống bộ nhớ ảo sử dụng một kỹ thuật gọi là phân trang (paging), mà chúng ta sẽ mô tả
ngay bây giờ. Trên bất kỳ máy tính nào, các chương trình tham chiếu đến một tập hợp các địa chỉ bộ
nhớ. Khi một chương trình thực thi một lệnh như

MOV REG,1000

nó thực hiện việc sao chép nội dung của địa chỉ bộ nhớ 1000 vào REG (hoặc ngược lại, tùy thuộc vào máy
tính). Các địa chỉ có thể được tạo ra bằng cách sử dụng chỉ số, thanh ghi cơ sở, thanh ghi đoạn, và các
cách khác.

Các địa chỉ được chương trình tạo ra được gọi là địa chỉ ảo và tạo thành không gian địa chỉ ảo. Trên các
máy tính không có bộ nhớ ảo, địa chỉ ảo được đặt trực tiếp lên bus bộ nhớ và gây ra việc đọc hoặc ghi từ
bộ nhớ vật lý có cùng địa chỉ. Khi sử dụng bộ nhớ ảo, các địa chỉ ảo không đi trực tiếp đến bus bộ nhớ.
Thay vào đó, chúng đi đến một Đơn vị Quản lý Bộ nhớ (MMU - Memory Management Unit) để ánh xạ
các địa chỉ ảo sang các địa chỉ bộ nhớ vật lý, như minh họa trong Hình 3-8.
Một ví dụ rất đơn giản về cách ánh xạ này hoạt động được hiển thị trong Hình 3-9. Trong ví dụ này, chúng
ta có một máy tính tạo ra các địa chỉ 16-bit, từ 0 đến 64K−1. Đây là các địa chỉ ảo. Tuy nhiên, máy tính
này chỉ có 32 KB bộ nhớ vật lý. Vì vậy, mặc dù có thể viết các chương trình 64 KB, chúng không thể được
tải toàn bộ vào bộ nhớ và chạy. Tuy nhiên, một bản sao hoàn chỉnh của hình ảnh nhân chương trình, lên
đến 64 KB, phải có mặt trên đĩa để các phần có thể được đưa vào khi cần thiết.

Không gian địa chỉ ảo bao gồm các đơn vị có kích thước cố định gọi là trang. Các đơn vị tương ứng trong
bộ nhớ vật lý được gọi là khung trang. Các trang và khung trang thường có cùng kích thước. Trong ví dụ
này, chúng có kích thước 4 KB, nhưng kích thước trang từ 512 byte đến một gigabyte đã được sử dụng
trong các hệ thống thực. Với 64 KB không gian địa chỉ ảo và 32 KB bộ nhớ vật lý, chúng ta có 16 trang ảo
và 8 khung trang. Việc chuyển đổi giữa RAM và đĩa luôn diễn ra theo từng trang. Nhiều bộ vi xử lý hỗ trợ
nhiều kích thước trang khác nhau có thể được kết hợp theo ý muốn của hệ điều hành. Ví dụ, kiến trúc
x86-64 hỗ trợ các trang 4-KB, 2-MB, và 1-GB, do đó chúng ta có thể sử dụng các trang 4-KB cho các ứng
dụng người dùng và một trang 1-GB duy nhất cho kernel. Chúng ta sẽ thấy sau tại sao đôi khi tốt hơn khi
sử dụng một trang lớn duy nhất, thay vì một số lượng lớn các trang nhỏ.

Ký hiệu trong Hình 3-9 như sau. Phạm vi được đánh dấu 0K–4K có nghĩa là các địa chỉ ảo hoặc vật lý
trong trang đó là từ 0 đến 4095. Phạm vi 4K–8K đề cập đến các địa chỉ từ 4096 đến 8191, và cứ thế. Mỗi
trang chứa chính xác 4096 địa chỉ bắt đầu từ một bội số của 4096 và kết thúc ngay trước một bội số của
4096.

Khi chương trình cố gắng truy cập địa chỉ 0, ví dụ, sử dụng lệnh

MOV REG,0

địa chỉ ảo 0 được gửi đến MMU. MMU thấy rằng địa chỉ ảo này nằm trong trang 0 (0 đến 4095), mà theo
ánh xạ của nó là khung trang 2 (8192 đến 12287). Nó sẽ chuyển đổi địa chỉ thành 8192 và xuất địa chỉ
8192 lên bus. Bộ nhớ không biết gì về MMU và chỉ thấy một yêu cầu đọc hoặc ghi địa chỉ 8192, và nó sẽ
thực hiện yêu cầu đó. Do đó, MMU đã thực hiện việc ánh xạ tất cả các địa chỉ ảo từ 0 đến 4095 sang các
địa chỉ vật lý từ 8192 đến 12287. Tương tự, lệnh

MOV REG,8192

thực sự được chuyển đổi thành

MOV REG,24576
Vì địa chỉ ảo 8192 (trong trang ảo 2) được ánh xạ tới 24576 (trong khung trang vật lý 6). Ví dụ thứ ba, địa
chỉ ảo 20500 nằm cách đầu trang ảo 5 (địa chỉ ảo từ 20480 đến 24575) 20 byte và ánh xạ tới địa chỉ vật lý
12288 + 20 = 12308. Khả năng ánh xạ 16 trang ảo tới bất kỳ trong số 8 khung trang bằng cách thiết lập
bản đồ của MMU thích hợp không tự giải quyết được vấn đề không gian địa chỉ ảo lớn hơn bộ nhớ vật lý.
Vì chỉ có 8 khung trang vật lý, chỉ 8 trang ảo trong Hình 3-9 được ánh xạ tới bộ nhớ vật lý. Các trang còn
lại, được đánh dấu bằng dấu chéo trong hình, không được ánh xạ. Trong phần cứng thực tế, một bit Hiện
diện/vắng mặt (Present/absent bit) theo dõi các trang nào có mặt trong bộ nhớ vật lý.

Điều gì xảy ra nếu chương trình tham chiếu một địa chỉ không được ánh xạ, ví dụ, bằng cách sử dụng
lệnh

MOV REG,32780

là byte 12 trong trang ảo 8 (bắt đầu từ 32768)? MMU nhận thấy rằng trang này không được ánh xạ
(được chỉ định bằng dấu chéo trong hình) và gây ra việc CPU chuyển sang hệ điều hành. Việc chuyển này
được gọi là lỗi trang (page fault). Hệ điều hành chọn một khung trang ít được sử dụng và ghi nội dung
của nó trở lại đĩa (nếu nó chưa có trên đĩa). Sau đó, nó nạp trang vừa được tham chiếu vào khung trang
vừa được giải phóng từ đĩa, thay đổi bản đồ, và khởi động lại lệnh bị lỗi. Ví dụ, nếu hệ điều hành quyết
định loại bỏ khung trang 1, nó sẽ nạp trang ảo 8 vào địa chỉ vật lý 4096 và thực hiện hai thay đổi đối với
bản đồ MMU. Đầu tiên, nó đánh dấu mục của trang ảo 1 là không được ánh xạ, để bẫy bất kỳ lần truy
cập nào trong tương lai tới các địa chỉ ảo từ 4096 đến 8191. Sau đó, nó thay thế dấu chéo trong mục của
trang ảo 8 bằng số 1, để khi lệnh bị lỗi được thực hiện lại, nó sẽ ánh xạ địa chỉ ảo 32780 tới địa chỉ vật lý
4108 (4096 + 12).

Bây giờ chúng ta hãy xem bên trong MMU để xem nó hoạt động như thế nào và tại sao chúng ta chọn
kích thước trang là lũy thừa của 2. Trong Hình 3-10, chúng ta thấy một ví dụ về địa chỉ ảo 8196
(0010000000000100 trong nhị phân) được ánh xạ bằng cách sử dụng bản đồ MMU của Hình 3-9. Địa chỉ
ảo 16-bit đầu vào được chia thành số trang 4-bit và phần bù 12-bit. Với 4 bit cho số trang, chúng ta có
thể có 16 trang, và với 12 bit cho phần bù, chúng ta có thể địa chỉ hóa tất cả 4096 byte trong một trang.
Số trang được sử dụng làm chỉ mục vào bảng trang, cho ra số của khung trang tương ứng với trang ảo
đó. Nếu bit Hiện diện/vắng mặt là 0, một bẫy tới hệ điều hành sẽ xảy ra. Nếu bit là 1, số khung trang tìm
thấy trong bảng trang được sao chép vào 3 bit cao của thanh ghi đầu ra, cùng với phần bù 12 bit, được
sao chép không thay đổi từ địa chỉ ảo đầu vào. Chúng tạo thành một địa chỉ vật lý 15 bit. Thanh ghi đầu
ra sau đó được đặt lên bus bộ nhớ dưới dạng địa chỉ bộ nhớ vật lý.

You might also like