[He Dieu Hanh] Chương 7. Bộ nhớ ảo
Chương 7: BỘ
NHỚ ẢO
Nếu đặt toàn thể
không gian địa chỉ vào bộ nhớ vật lý, thì kích thước của chương trình bị giới
hạn bởi kích thước bộ nhớ vật lý.
Thực tế, trong
nhiều trường hợp, chúng ta không cần phải nạp toàn bộ chương trình vào bộ nhớ vật
lý cùng một lúc, vì tại một thời điểm chỉ có một chỉ thị của tiến trình được xử
lý. Ví dụ, các chương trình đều có một đoạn code xử lý lỗi, nhưng đoạn code này
hầu như rất ít khi được sử dụng vì hiếm khi xảy ra lỗi, trong trường hợp này,
không cần thiết phải nạp đoạn code xử lý lỗi từ đầu.
Từ nhận xét trên,
một giải pháp được đề xuất là cho phép thực hiện một chương trình chỉ được nạp
từng phần vào bộ nhớ vật lý. Ý tưởng chính của giải pháp này là tại mỗi thời
điểm chỉ lưu trữ trong bộ nhớ vật lý các chỉ thị và dữ liệu của chương trình
cần thiết cho việc thi hành tại thời điểm đó. Khi cần đến các chỉ thị khác,
những chỉ thị mới sẽ được nạp vào bộ nhớ, tại vị trí trước đó bị chiếm giữ bởi
các chỉ thị nay không còn cần đến nữa. Với giải pháp này, một chương trình có
thể lớn hơn kích thước của vùng nhớ cấp phát cho nó.
Một cách để thực
hiện ý tưởng của giải pháp trên đây là sử dụng kỹ thuật overlay. Kỹ
thuật overlay không đòi hỏi bất kỳ sự trợ giúp đặc biệt nào của hệ điều hành,
nhưng trái lại, lập trình viên phải biết cách lập trình theo cấu trúc overlay,
và điều này đòi hỏi khá nhiều công sức.
Để giải phóng lập
trình viên khỏi các suy tư về giới hạn của bộ nhớ, mà cũng không tăng thêm khó
khăn cho công việc lập trình của họ, người ta nghĩ đến các kỹ thuật tự động,
cho phép xử lý một chương trình có kích thước lớn chỉ với một vùng nhớ có kích
thước nhỏ. Giải pháp được tìm thấy với khái niệm bộ nhớ ảo (virtual memory).
7.1.1. Định
nghĩa
Bộ nhớ ảo là một
kỹ thuật cho phép xử lý một tiến trình không được nạp toàn bộ vào bộ nhớ vật
lý. Bộ nhớ ảo mô hình hóa bộ nhớ như một bảng lưu trữ rất lớn và đồng nhất,
tách biệt hẳn khái niệm không gian địa chỉ và không gian vật lý. Người sử dụng
chỉ nhìn thấy và làm việc trong không gian địa chỉ ảo, việc chuyển đổi sang không
gian vật lý do hệ điều hành thực hiện với sự trợ giúp của các cơ chế phần cứng
cụ thể.
a) Thảo luận:
Cần kết hợp kỹ
thuật swapping để chuyển các phần của chương trình vào-ra giữa bộ nhớ
chính và bộ nhớ phụ khi cần thiết.
Nhờ việc tách biệt
bộ nhớ ảo và bộ nhớ vật lý, có thể tổ chức một bộ nhớ ảo có kích thước lớn hơn
bộ nhớ vật lý.
Bộ nhớ ảo cho phép
giảm nhẹ công việc của lập trình viên vì họ không cần bận tâm đến giới hạn của
vùng nhớ vật lý, cũng như không cần tổ chức chương trình theo cấu trúc overlays.
Hình
2.24 Bộ nhớ ảo
Bộ nhớ ảo
thường được thực hiện với kỹ thuật phân trang theo yêu cầu (demand
paging). Cũng có thể sử dụng kỹ thuật phân đoạn theo yêu cầu (demand
segmentation) để cài đặt bộ nhớ ảo, tuy nhiên việc cấp phát và thay thế các
phân đoạn phức tạp hơn thao tác trên trang, vì kích thước không bằng nhau của
các đoạn.
a) Phân trang
theo yêu cầu (demand paging)
Một hệ thống phân
trang theo yêu cầu là hệ thống sử dụng kỹ thuật phân trang kết hợp với kỹ thuật
swapping. Một tiến trình được xem như một tập các trang, thường trú trên bộ nhớ
phụ (thường là đĩa). Khi cần xử lý, tiến trình sẽ được nạp vào bộ nhớ chính.
Nhưng thay vì nạp toàn bộ chương trình, chỉ những trang cần thiết trong thời
điểm hiện tại mới được nạp vào bộ nhớ. Như vậy một trang chỉ được nạp vào bộ
nhớ chính khi có yêu cầu.
Với mô hình này,
cần cung cấp một cơ chế phần cứng giúp phân biệt các trang đang ở trong bộ nhớ
chính và các trang trên đĩa. Có thể sử dụng lại bit valid-invalid nhưng
với ngữ nghĩa mới:
- valid: trang
tương ứng là hợp lệ và đang ở trong bộ nhớ chính.
- invalid: hoặc
trang bất hợp lệ (không thuộc về không gian địa chỉ của tiến trình) hoặc trang
hợp lệ nhưng đang được lưu trên bộ nhớ phụ.
Một phần tử trong
bảng trang mô tả cho một trang không nằm trong bộ nhớ chính, sẽ được đánh dấu invalid
và chứa địa chỉ của trang trên bộ nhớ phụ.
b) Cơ chế phần
cứng:
Cơ chế phần cứng
hỗ trợ kỹ thuật phân trang theo yêu cầu là sự kết hợp của cơ chế hỗ trợ kỹ
thuật phân trang và kỹ thuật swapping:
- Bảng trang:
Cấu trúc bảng trang phải cho phép phản ánh tình trạng của một trang là đang nằm
trong bộ nhớ chính hay bộ nhớ phụ.
- Bộ nhớ phụ:
Bộ nhớ phụ lưu trữ những trang không được nạp vào bộ nhớ chính. Bộ nhớ phụ
thường được sử dụng là đĩa, và vùng không gian đĩa dùng để lưu trữ tạm các
trang trong kỹ thuật swapping được gọi là không gian swapping.
Hình
2.24 Bảng trang với một số trang trên
bộ nhớ phụ
c) Lỗi trang
Truy xuất đến một
trang được đánh dấu bất hợp lệ sẽ làm phát sinh một lỗi trang (page
fault). Khi dò tìm trong bảng trang để lấy các thông tin cần thiết cho việc
chuyển đổi địa chỉ, nếu nhận thấy trang đang được yêu cầu truy xuất là bất hợp
lệ, cơ chế phần cứng sẽ phát sinh một ngắt để báo cho hệ điều hành. Hệ điều
hành sẽ xử lý lỗi trang như sau:
B1: Kiểm tra truy
xuất đến bộ nhớ là hợp lệ hay bất hợp lệ.
Nếu
truy xuất bất hợp lệ: kết thúc tiến trình.
Ngược
lại: đến bước 2.
B2: Tìm vị trí chứa trang muốn
truy xuất trên đĩa.
B3: Tìm một khung trang trống
trong bộ nhớ chính:
Nếu
tìm thấy: đến bước 4.
Nếu
không còn khung trang trống, chọn một khung trang “nạn nhân” và chuyển trang “nạn
nhân” ra bộ nhớ phụ (lưu nội dung của trang đang chiếm giữ khung trang này lên
đĩa), cập nhật bảng trang tương ứng rồi đến bước 4.
B4: Chuyển trang muốn truy xuất
từ bộ nhớ phụ vào bộ nhớ chính: nạp trang cần truy xuất vào khung trang trống
đã chọn (hay vừa mới làm trống), cập nhật nội dung bảng trang, bảng khung trang
tương ứng.
B5: Tái kích hoạt tiến trình
người sử dụng.
Khi xảy ra một lỗi
trang, cần phải mang trang vắng mặt vào bộ nhớ. Nếu không có một khung trang
nào trống, hệ điều hành cần thực hiện công việc thay thế trang – chọn
một trang đang nằm trong bộ nhớ mà không được sử dụng tại thời điểm hiện tại và
chuyển nó ra không gian swapping trên đĩa để giải phóng một khung trang
dành chỗ nạp trang cần truy xuất vào bộ nhớ.
Như vậy nếu không
có khung trang trống, thì mỗi khi xảy ra lỗi trang cần phải thực hiện hai thao
tác chuyển trang: chuyển một trang ra bộ nhớ phụ và nạp một trang khác vào bộ
nhớ chính. Có thể giảm bớt số lần chuyển trang bằng cách sử dụng thêm một bit cập
nhật (dirty bit). Bit này được gắn với mỗi trang để phản ánh tình trạng
trang có bị cập nhật hay không: giá trị của bit được cơ chế phần cứng đặt là 1
mỗi lần có một từ được ghi vào trang, để ghi nhận nội dung trang có bị sửa đổi.
Khi cần thay thế một trang, nếu bit cập nhật có giá trị là 1 thì trang cần được
lưu lại trên đĩa, ngược lại, nếu bit cập nhật là 0, nghĩa là trang không
bị thay đổi, thì không cần lưu trữ trang trở lại đĩa.
số hiệu trang
|
bit
valid-invalid
|
dirty bit
|
Hình
4.27 Cấu trúc một phần tử trong bảng
trang
Sự thay thế trang
là cần thiết cho kỹ thuật phân trang theo yêu cầu. Nhờ cơ chế này, hệ thống có
thể hoàn toàn tách rời bộ nhớ ảo và bộ nhớ vật lý, cung cấp cho lập trình viên
một bộ nhớ ảo rất lớn trên một bộ nhớ vật lý có thể bé hơn rất nhiều lần.
7.2.1. Sự thi
hành phân trang theo yêu cầu
Việc áp dụng kỹ
thuật phân trang theo yêu cầu có thể ảnh hưởng mạnh đến tình hình hoạt động của
hệ thống.
Giả sử p là
xác suất xảy ra một lỗi trang (0 p 1):
p = 0: không có
lỗi trang nào.
p = 1: mỗi truy
xuất sẽ phát sinh một lỗi trang.
Thời gian thật sự
cần để thực hiện một truy xuất bộ nhớ (TEA) là:
TEA = (1-p)ma + p
(tdp) [+ swap out ] + swap in + tái kích hoạt
Trong công thức
này, ma là thời gian truy xuất bộ nhớ, tdp thời gian xử lý lỗi
trang.
Có thể thấy rằng,
để duy trì ở một mức độ chấp nhận được sự chậm trễ trong hoạt động của hệ thống
do phân trang, cần phải duy trì tỷ lệ phát sinh lỗi trang thấp.
Hơn nữa, để cài
đặt kỹ thuật phân trang theo yêu cầu, cần phải giải quyết hai vấn đề chính yếu:
xây dựng một thuật toán cấp phát khung trang, và thuật toán thay thế
trang.
Vấn đề chính khi
thay thế trang là chọn lựa một trang “nạn nhân” để chuyển ra bộ nhớ phụ. Có
nhiều thuật toán thay thế trang khác nhau, nhưng tất cả cùng chung một mục tiêu:
chọn trang “nạn nhân” là trang mà sau khi thay thế sẽ gây ra ít lỗi trang nhất.
Có thể đánh giá
hiệu qủa của một thuật toán bằng cách xử lý trên một chuỗi các địa chỉ cần
truy xuất và tính toán số lượng lỗi trang phát sinh.
Ví dụ: Giả sử theo vết xử lý của một tiến trình và nhận
thấy tiến trình thực hiện truy xuất các địa chỉ theo thứ tự sau:
0100, 0432, 0101,
0162, 0102, 0103, 0104, 0101, 0611, 0102, 0103,0104, 0101, 0610, 0102, 0103,
0104, 0101, 0609, 0102, 0105
Nếu có kích thước
của một trang là 100 bytes, có thể viết lại chuỗi truy xuất trên giản
lược hơn như sau:
1, 4, 1, 6, 1, 6,
1, 6, 1
Để xác định số các
lỗi trang xảy ra khi sử dụng một thuật toán thay thế trang nào đó trên một
chuỗi truy xuất cụ thể, còn cần phải biết số lượng khung trang sử dụng trong hệ
thống.
Để minh hoạ các
thuật toán thay thế trang sẽ trình bày, chuỗi truy xuất được sử dụng là:
7, 0, 1, 2, 0, 3,
0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1
a) Thuật toán FIFO
a.1 Tiếp cận:
Ghi nhận thời điểm một trang được mang vào bộ nhớ chính. Khi cần thay thế
trang, trang ở trong bộ nhớ lâu nhất sẽ được chọn
a.2 Ví dụ: sử
dụng 3 khung trang, ban đầu cả 3 đều trống:
7
|
0
|
1
|
2
|
0
|
3
|
0
|
4
|
2
|
3
|
0
|
3
|
2
|
1
|
2
|
0
|
1
|
7
|
0
|
1
|
7
|
7
|
7
|
2
|
2
|
2
|
2
|
4
|
4
|
4
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
7
|
7
|
7
|
0
|
0
|
0
|
0
|
3
|
3
|
3
|
2
|
2
|
2
|
2
|
2
|
1
|
1
|
1
|
1
|
1
|
0
|
0
|
|
1
|
1
|
1
|
1
|
0
|
0
|
0
|
3
|
3
|
3
|
3
|
3
|
2
|
2
|
2
|
2
|
2
|
1
|
||
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
Ghi chú: *: có lỗi trang
a.3 Thảo luận:
Để áp dụng thuật
toán FIFO, thực tế không nhất thiết phải ghi nhận thời điểm mỗi trang được nạp
vào bộ nhớ, mà chỉ cần tổ chức quản lý các trang trong bộ nhớ trong một danh
sách FIFO, khi đó trang đầu danh sách sẽ được chọn để thay thế.
Thuật toán thay
thế trang FIFO dễ hiểu, dễ cài đặt. Tuy nhiên khi thực hiện không phải lúc nào
cũng có kết quả tốt: trang được chọn để thay thế có thể là trang chứa nhiều dữ
liệu cần thiết, thường xuyên được sử dụng nên được nạp sớm, do vậy khi bị
chuyển ra bộ nhớ phụ sẽ nhanh chóng gây ra lỗi trang.
Số lượng lỗi trang
xảy ra sẽ tăng lên khi số lượng khung trang sử dụng tăng. Hiện tượng này gọi là
nghịch lý Belady.
Ví dụ: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
Sử dụng 3 khung
trang, sẽ có 9 lỗi trang phát sinh
1
|
2
|
3
|
4
|
1
|
2
|
5
|
1
|
2
|
3
|
4
|
5
|
1
|
1
|
1
|
4
|
4
|
4
|
5
|
5
|
5
|
5
|
5
|
5
|
2
|
2
|
2
|
1
|
1
|
1
|
1
|
1
|
3
|
3
|
3
|
|
3
|
3
|
3
|
2
|
2
|
2
|
2
|
2
|
4
|
4
|
||
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
Sử
dụng 4 khung trang, sẽ có 10 lỗi trang phát sinh
1
|
2
|
3
|
4
|
1
|
2
|
5
|
1
|
2
|
3
|
4
|
5
|
1
|
1
|
1
|
1
|
1
|
1
|
5
|
5
|
5
|
5
|
4
|
4
|
2
|
2
|
2
|
2
|
2
|
2
|
1
|
1
|
1
|
1
|
5
|
|
3
|
3
|
3
|
3
|
3
|
3
|
2
|
2
|
2
|
2
|
||
4
|
4
|
4
|
4
|
4
|
4
|
3
|
3
|
3
|
|||
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
b) Thuật toán tối ưu
b.1 Tiếp cận: Thay thế trang sẽ lâu được sử dụng nhất trong tương
lai.
Ví dụ: sử dụng 3 khung trang, khởi đầu đều trống:
7
|
0
|
1
|
2
|
0
|
3
|
0
|
4
|
2
|
3
|
0
|
3
|
2
|
1
|
2
|
0
|
1
|
7
|
0
|
1
|
7
|
7
|
7
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
7
|
7
|
7
|
0
|
0
|
0
|
0
|
0
|
0
|
4
|
4
|
4
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
|
1
|
1
|
1
|
3
|
3
|
3
|
3
|
3
|
3
|
3
|
3
|
1
|
1
|
1
|
1
|
1
|
1
|
1
|
||
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
b.2 Thảo luận:
Thuật toán này bảo
đảm số lượng lỗi trang phát sinh là thấp nhất, nó cũng không gánh chịu nghịch
lý Belady, tuy nhiên, đây là một thuật toán không khả thi trong thực tế, vì
không thể biết trước chuỗi truy xuất của tiến trình!
c) Thuật toán “Lâu nhất chưa sử dụng” (Least-recently-used
LRU)
c.1 Tiếp cận: Với mỗi trang, ghi nhận thời điểm cuối cùng trang
được truy cập, trang được chọn để thay thế sẽ là trang lâu nhất chưa được truy
xuất.
c.2 Ví dụ: sử dụng 3 khung trang, khởi đầu đều trống:
7
|
0
|
1
|
2
|
0
|
3
|
0
|
4
|
2
|
3
|
0
|
3
|
2
|
1
|
2
|
0
|
1
|
7
|
0
|
1
|
7
|
7
|
7
|
2
|
2
|
2
|
2
|
4
|
4
|
4
|
0
|
0
|
0
|
1
|
1
|
1
|
1
|
1
|
1
|
1
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
3
|
3
|
3
|
3
|
3
|
3
|
0
|
0
|
0
|
0
|
0
|
|
1
|
1
|
1
|
3
|
3
|
3
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
2
|
7
|
7
|
7
|
||
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
*
|
c.3 Thảo luận:
Thuật toán FIFO sử
dụng thời điểm nạp để chọn trang thay thế, thuật toán tối ưu lại dùng thời điểm
trang sẽ được sử dụng, vì thời điểm này không thể xác định trước nên
thuật toán LRU phải dùng thời điểm cuối cùng trang được truy xuất – dùng quá
khứ gần để dự đoán tương lai.
Thuật toán này đòi
hỏi phải được cơ chế phần cứng hỗ trợ để xác định một thứ tự cho các trang theo
thời điểm truy xuất cuối cùng. Có thể cài đặt theo một trong hai cách:
c.3.1 Sử dụng bộ đếm:
- Thêm vào cấu trúc của mỗi phần tử trong bảng trang một
trường ghi nhận thời điểm truy xuất mới nhất, và thêm vào cấu trúc của CPU một
bộ đếm.
- Mỗi lần có sự truy xuất bộ nhớ, giá trị của counter
tăng lên 1.
- Mỗi lần thực hiện truy xuất đến một trang, giá trị của
counter được ghi nhận vào trường thời điểm truy xuất mới nhất của phần tử tương
ứng với trang trong bảng trang.
- Thay thế trang có giá trị trường thời điểm truy xuất
mới nhất là nhỏ nhất.
c.3.2 Sử dụng stack:
- Tổ chức một stack lưu trữ các số hiệu trang.
- Mỗi khi thực hiện một truy xuất đến một trang, số hiệu
của trang sẽ được xóa khỏi vị trí hiện hành trong stack và đưa lên đầu stack.
- Trang ở đỉnh stack là trang được truy xuất gần nhất,
và trang ở đáy stack là trang lâu nhất chưa được sử dụng.
d) Các thuật toán xấp xỉ LRU
Có ít hệ thống
được cung cấp đủ các hỗ trợ phần cứng để cài đặt được thuật toán LRU thật sự.
Tuy nhiên, nhiều hệ thống được trang bị thêm một bit tham khảo (reference):
- Một bit reference, được khởi gán là 0, được gắn với
một phần tử trong bảng trang.
- Bit reference của một trang được phần cứng đặt giá trị
1 mỗi lần trang tương ứng được truy cập, và được phần cứng gán trở về 0 sau
từng chu kỳ qui định trước.
- Sau từng chu kỳ qui định trước, kiểm tra giá trị của
các bit reference, có thể xác định được trang nào đã được truy xuất đến và
trang nào không, sau khi đã kiểm tra xong, các bit reference được phần cứng gán
trở về 0.
- Với bit reference, có thể biết được trang nào đã được
truy xuất, nhưng không biết được thứ tự truy xuất. Thông tin không đầy đủ này
dẫn đến nhiều thuật toán xấp xỉ LRU khác nhau.
số hiệu trang
|
bit
valid-invalid
|
dirty bit
|
bit reference
|
Hình
4.28 Cấu trúc một phần tử trong bảng
trang
d.1 Thuật
toán với các bit reference phụ trợ
Tiếp cận: Có thể thu thập thêm nhiều thông tin về thứ tự truy
xuất hơn bằng cách lưu trữ các bit references sau từng khoảng thời gian đều đặn:
- Với mỗi trang, sử dụng thêm 8 bit lịch sử (history) trong
bảng trang.
- Sau từng khoảng thời gian nhất định (thường là 100
millisecondes), một ngắt đồng hồ được phát sinh, và quyền điều khiển được
chuyển cho hệ điều hành. Hệ điều hành đặt bit reference của mỗi trang vào bit
cao nhất trong 8 bit phụ trợ của trang đó bằng cách đẩy các bit khác sang phải
1 vị trí, bỏ luôn bit thấp nhất.
- Như vậy 8 bit thêm vào này sẽ lưu trữ tình hình truy
xuất đến trang trong 8 chu kỳ cuối cùng.
- Nếu giá trị của 8 bit là 00000000, thì trang tương ứng
đã không được dùng đến suốt 8 chu kỳ cuối cùng, ngược lại nếu nó được dùng đến
ít nhất 1 lần trong mỗi chu kỳ, thì 8 bit phụ trợ sẽ là 11111111. Một trang mà
8 bit phụ trợ có giá trị 11000100 sẽ được truy xuất gần thời điểm hiện tại hơn
trang có 8 bit phụ trợ là 01110111.
- Nếu xét 8 bit phụ trợ này như một số nguyên không dấu,
thì trang LRU là trang có số phụ trợ nhỏ nhất.
Ví dụ:
0
|
0
|
1
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
|
HR =11000100
|
||||||||||
HR =11100010
|
||||||||||
HR =01110001
|
Thảo luận: Số lượng các bit lịch sử có thể thay đổi tùy theo
phần cứng, và phải được chọn sao cho việc cập nhật là nhanh nhất có thể.
d.2 Thuật
toán “cơ hội thứ hai”
Tiếp cận: Sử dụng một bit reference duy nhất. Thuật toán cơ sở
vẫn là FIFO, tuy nhiên khi chọn được một trang theo tiêu chuẩn FIFO, kiểm tra
bit reference của trang đó:
- Nếu giá trị của bit reference là 0, thay thế trang đã
chọn.
- Ngược lại, cho trang này một cơ hội thứ hai, và chọn
trang FIFO tiếp theo.
- Khi một trang được cho cơ hội thứ hai, giá trị của bit
reference được đặt lại là 0, và thời điểm vào Ready List được cập nhật lại là
thời điểm hiện tại.
- Một trang đã được cho cơ hội thứ hai sẽ không bị thay
thế trước khi hệ thống đã thay thế hết những trang khác. Hơn nữa, nếu trang
thường xuyên được sử dụng, bit reference của nó sẽ duy trì được giá trị 1, và
trang hầu như không bao giờ bị thay thế.
Thảo luận:
Hình
2.29 Thuật toán thay thế trang “cơ
hội thứ hai”
d.3 Thuật
toán “cơ hội thứ hai” nâng cao (Not Recently Used - NRU)
Tiếp cận: xem các bit reference và dirty bit như một cặp có thứ
tự.
Với hai bit này,
có thể có 4 tổ hợp tạo thành 4 lớp sau:
- (0,0) không truy xuất, không sửa đổi: đây là trang tốt
nhất để thay thế.
- (0,1) không truy xuất gần đây, nhưng đã bị sửa đổi: trường
hợp này không thật tốt, vì trang cần được lưu trữ lại trước khi thay thế.
- (1,0) được truy xuất gần đây, nhưng không bị sửa đổi: trang
có thể nhanh chóng được tiếp tục được sử dụng.
- (1,1) được truy xuất gần đây, và bị sửa đổi: trang có
thể nhanh chóng được tiếp tục được sử dụng, và trước khi thay thế cần phải được
lưu trữ lại.
Lớp 1 có độ ưu
tiên thấp nhất, và lớp 4 có độ ưu tiên cao nhất.
Một trang sẽ thuộc
về một trong bốn lớp trên, tùy vào bit reference và dirty bit của trang đó.
Trang được chọn để
thay thế là trang đầu tiên tìm thấy trong lớp có độ ưu tiên thấp nhất và khác
rỗng.
e) Các thuật toán thống kê
Tiếp cận: sử dụng một biến đếm lưu trữ số lần truy xuất đến
một trang, và phát triển hai thuật toán sau:
- Thuật toán LFU:
thay thế trang có giá trị biến đếm nhỏ nhất, nghĩa là trang ít được sử dụng
nhất.
- Thuật toán MFU:
thay thế trang có giá trị biến đếm lớn nhất, nghĩa là trang được sử dụng nhiều
nhất (most frequently used).
7.3 Cấp phát
khung trang
Vấn đề đặt ra là
làm thế nào để cấp phát một vùng nhớ tự do có kích thước cố định cho các tiến
trình khác nhau?
Trong trường hợp
đơn giản nhất của bộ nhớ ảo là hệ đơn nhiệm, có thể cấp phát cho tiến trình duy
nhất của người dùng tất cả các khung trang trống.
Vấn đề nảy sinh
khi kết hợp kỹ thuật phân trang theo yêu cầu với sự đa chương: cần phải duy trì
nhiều tiến trình trong bộ nhớ cùng lúc, vậy mỗi tiến trình sẽ được cấp bao
nhiêu khung trang.
a) Số khung trang tối thiểu:
Với mỗi tiến
trình, cần phải cấp phát một số khung trang tối thiểu nào đó để tiến trình có
thể hoạt động. Số khung trang tối thiểu này được quy định bởi kiến trúc của của
một chỉ thị. Khi một lỗi trang xảy ra trước khi chỉ thị hiện hành hoàn tất, chỉ
thị đó cần được tái khởi động, lúc đó cần có đủ các khung trang để nạp tất cả
các trang mà một chỉ thị duy nhất có thể truy xuất.
Số khung trang tối
thiểu được qui định bởi kiến trúc máy tính, trong khi số khung trang tối đa
được xác định bởi dung lượng bộ nhớ vật lý có thể sử dụng.
b) Các thuật toán cấp phát khung trang
Có hai hướng tiếp
cận:
b.1 Cấp phát cố
định:
b.1.1 Cấp phát
công bằng: nếu có m khung trang và n tiến trình, mỗi tiến
trình được cấp m /n khung trang.
b.1.2 Cấp phát
theo tỷ lệ: tùy vào kích thước của tiến trình để cấp phát số khung trang:
si = kích thước của bộ nhớ ảo cho tiến trình pi
S = Σ si
m = số lượng tổng cộng khung trang có thể sử dụng
Cấp phát ai
khung trang cho tiến trình pi: ai = (si/S) m
b.2 Cấp phát
theo độ ưu tiên: sử dụng ý tưởng cấp phát theo tỷ lệ, nhưng số lượng khung
trang cấp cho tiến trình phụ thuộc vào độ ưu tiên của tiến trình, hơn là phụ
thuộc kích thước tiến trình:
Nếu tiến trình pi
phát sinh một lỗi trang, chọn một trong các khung trang của nó để thay thế,
hoặc chọn một khung trang của tiến trình khác với độ ưu tiên thấp hơn để thay
thế.
c) Thay thế
trang toàn cục hay cục bộ
Có thể phân các
thuật toán thay thế trang thành hai lớp chính:
- Thay thế toàn cục: khi lỗi trang xảy ra với một tiến trình, chọn trang “nạn nhân” từ tập
tất cả các khung trang trong hệ thống, bất kể khung trang đó đang được cấp phát
cho một tiến trình khác.
- Thay thế cục bộ:
yêu cầu chỉ được chọn trang thay thế trong tập các khung trang được cấp cho tiến
trình phát sinh lỗi trang.
Một khuyết điểm
của thuật toán thay thế toàn cục là các tiến trình không thể kiểm soát được tỷ
lệ phát sinh lỗi trang của mình. Vì thế, tuy thuật toán thay thế toàn cục nhìn
chung cho phép hệ thống có nhiều khả năng xử lý hơn, nhưng nó có thể dẫn hệ
thống đến tình trạng trì trệ toàn bộ (thrashing).
Nếu một tiến trình
không có đủ các khung trang để chứa những trang cần thiết cho xử lý, thì nó sẽ
thường xuyên phát sinh các lỗi trang, và vì thế phải dùng đến rất nhiều thời
gian sử dụng CPU để thực hiện thay thế trang. Một hoạt động phân trang như thế
được gọi là sự trì trệ (thrashing). Một tiến trình lâm vào trạng thái
trì trệ nếu nó sử dụng nhiều thời gian để thay thế trang hơn là để xử lý!
Hiện tượng trì trệ
này ảnh hưởng nghiêm trọng đến hoạt động hệ thống, xét tình huống sau:
- Hệ điều hành giám sát việc sử dụng CPU.
- Nếu hiệu suất sử dụng CPU quá thấp, hệ điều hành sẽ
nâng mức độ đa chương bằng cách đưa thêm một tiến trình mới vào hệ thống.
- Hệ thống có thể sử dụng thuật toán thay thế toàn cục
để chọn các trang nạn nhân thuộc một tiến trình bất kỳ để có chỗ nạp tiến trình
mới, có thể sẽ thay thế cả các trang của tiến trình đang xử lý hiện hành.
- Khi có nhiều tiến trình trong hệ thống hơn, thì một
tiến trình sẽ được cấp ít khung trang hơn, và do đó phát sinh nhiều lỗi trang
hơn.
- Khi các tiến trình phát sinh nhiều lỗi trang, chúng
phải trải qua nhiều thời gian chờ các thao tác thay thế trang hoàn tất, lúc đó
hiệu suất sử dụng CPU lại giảm.
- Hệ điều hành lại quay trở lại bước 1...
Theo kịch bản trên
đây, hệ thống sẽ lâm vào tình trạng luẩn quẩn của việc giải phóng các
trang để cấp phát thêm khung trang cho một tiến trình, và các tiến trình khác
lại thiếu khung trang... và các tiến trình không thể tiếp tục xử lý. Đây chính
là tình trạng trì trệ toàn bộ hệ thống. Khi tình trạng trì trệ này xảy
ra, hệ thống gần như mất khả năng xử lý, tốc độ phát sinh lỗi trang tăng cao
khủng khiếp, không công việc nào có thể kết thúc vì tất cả các tiến trình đều
bận rộn với việc phân trang!
Để ngăn cản tình
trạng trì trệ này xảy ra, cần phải cấp cho tiến trình đủ các khung trang
cần thiết để hoạt động. Vấn đề cần giải quyết là làm sao biết được tiến trình
cần bao nhiêu trang?
Mô hình cục bộ (Locality):
theo lý thuyết cục bộ, thì khi một
tiến trình xử lý, nó có khuynh hướng di chuyển từ nhóm trang cục bộ này đến
nhóm trang cục bộ khác. Một nhóm trang cục bộ là một tập các trang đang được
tiến trình dùng đến trong một khoảng thời gian. Một chương trình thường bao gồm
nhiều nhóm trang cục bộ khác nhau và chúng có thể giao nhau.
a) Mô hình “tập làm việc” (working set)
a.1 Tiếp cận:
Mô hình working
set đặt cơ sở trên lý thuyết cục bộ. Mô hình này sử dụng một tham số , để định nghĩa một cửa sổ cho working set. Giả sử
khảo sát đơn vị thời gian (lần
truy xuất trang) cuối cùng, tập các trang được tiến trình truy xuất đến trong lần truy cập cuối cùng
này được gọi là working set của tiến trình tại thời điểm hiện tại. Nếu
một trang đang được tiến trình truy xuất đến, nó sẽ nằm trong working set, nếu
nó không được sử dụng nữa, nó sẽ bị loại ra khỏi working set của tiến trình sau
đơn vị thời gian kể từ
lần truy xuất cuối cùng đến nó. Như vậy working set chính là một sự xấp xỉ của
khái niệm nhóm trang cục bộ.
Hình
2.30 Mô hình working set
Một thuộc tính rất
quan trọng của working set là kích thước của nó. Nếu tính toán kích thước
working set, WSSi, cho mỗi tiến trình trong hệ thống, thì có thể xem như:
D = Σ WSSi
với D là tổng số
khung trang yêu cầu cho toàn hệ thống. Mỗi tiến trình sử dụng các trang trong
working set của nó, nghĩa là tiến trình i yêu cầu WSSi khung
trang. Nếu tổng số trang yêu cầu vượt quá tổng số trang có thể sử dụng trong hệ
thống (D > m), thì sẽ xảy ra tình trạng trì trệ toàn bộ.
a.2 Sử dụng:
Hệ điều hành giám sát working set của mỗi tiến
trình và cấp phát cho tiến trình tối thiểu các khung trang để chứa đủ working
set của nó. Như vậy một tiến trình mới chỉ có thể được nạp vào hệ thống khi có
đủ khung trang tự do cho working set của nó. Nếu tổng số khung trang yêu cầu
của các tiến trình trong hệ thống vượt quá các khung trang có thể sử dụng, hệ
điều hành chọn một tiến trình để tạm dừng, giải phóng bớt các khung trang cho
các tiến trình khác hoàn tất.
a.3 Thảo luận:
Chiến lược working
set đã loại trừ được tình trạng trì trệ trong khi vẫn đảm bảo mức độ đa chương
của hệ thống là cao nhất có thể, cho phép sử dụng tối ưu CPU.
Điểm khó khăn của
mô hình này là theo vết của các working set của tiến trình trong từng thời
điểm. Có thể xấp xỉ mô hình working set với một ngắt đồng hồ sau từng chu kỳ
nhất định và một bit reference:
- Phát sinh một ngắt đồng hồ sau từng T lần truy xuất bộ
nhớ.
- Khi xảy ra một ngắt đồng hồ, kiểm tra các trang có bit
reference là 1, các trang này được xem như thuộc về working set.
Một hệ thống sử
dụng kỹ thuật phân trang theo yêu cầu thuần túy (một trang không bao giờ được
nạp trước khi có yêu cầu truy xuất) để lộ một đặc điểm khá bất lợi: một số
lượng lớn lỗi trang xảy ra khi khởi động tiến trình. Tình trạng này là hậu quả
của khuynh hướng đạt tới việc đưa nhóm trang cục bộ vào bộ nhớ. Tình trạng này
cũng có thể xảy ra khi một tiến trình bị chuyển tạm thời ra bộ nhớ phụ, khi
được tái kích hoạt, tất cả các trang của tiến trình đã được chuyển lên đĩa phải
được mang trở lại vào bộ nhớ, và một loạt lỗi trang lại xảy ra. Để ngăn cản
tình hình lỗi trang xảy ra quá nhiều tại thời điểm khởi động tiến trình, có thể
sử dụng kỹ thuật tiền phân trang (prepaging): nạp vào bộ nhớ một lần tất cả các
trang trong working set của tiến trình.
Tiếp cận: Tần suất lỗi trang rất cao khiến tình trạng trì trệ hệ
thống có thể xảy ra.
- Khi tần suất lỗi trang quá cao, tiến trình cần thêm
một số khung trang.
- Khi tần suất lỗi trang quá thấp, tiến trình có thể sở
hữu nhiều khung trang hơn mức cần thiết.
Có thể thiết lập
một giá trị chặn trên và chặn dưới cho tần suất xảy ra lỗi trang, và trực tiếp
ước lượng và kiểm soát tần suất lỗi trang để ngăn chặn tình trang trì trệ xảy
ra:
- Nếu tần suất lỗi trang vượt quá chặn trên, cấp cho
tiến trình thêm một khung trang.
- Nếu tần suất lỗi trang thấp hơn chặn dưới, thu hồi bớt
một khung trang từ tiến trình.
7.4 Tóm tắt
Các kỹ thuật hỗ
trợ các mô hình tổ chức bộ nhớ hiện đại:
- Swapping: sử
dụng thêm bộ nhớ phụ để lưu trữ tạm các tiến trình đang bị khóa, nhờ vậy có thể
tăng mức độ đa chương của hệ thống với cấu hình máy có dung lượng bộ nhớ chính
thấp.
- Bộ nhớ ảo: sử
dụng kỹ thuật phân trang theo yêu cầu, kết hợp thêm kỹ thuật swapping để mở
rộng bộ nhớ chính. Tách biệt không gian địa chỉ và không gian vật lý, nhờ đó có
thể xử lý các chương trình có kích thước lớn hơn bộ nhớ vật lý thật sự
Khi cài đặt bộ nhớ
ảo, phải sử dụng một thuật toán thay thế trang thích hợp để chọn các trang bị
chuyển tạm thời ra bộ nhớ phụ, dành chỗ trong bộ nhớ chính cho trang mới. Các
thuật toán thay thế thường sử dụng là FIFO, LRU và các thuật toán xấp xỉ LRU,
các thuật toán thống kê NFU, MFU...
Khi mức độ đa
chương tăng cao đến một chừng mực nào đó, hệ thống có thể lâm vào tình trạng
trì trệ do tất cả các tiến trình đều thiếu khung trang. Có thể áp dụng mô hình
working set để dành cho mỗi tiến trình đủ các khung trang cần thiết tại một
thời điểm, từ đó có thể ngăn chặn tình trạng trì trệ xảy ra.
7.5 Củng
cố bài học
Các câu hỏi
cần trả lời được sau bài học này:
1. Bộ nhớ ảo là gì?
2. Sự thật đằng
sau ảo giác: giới hạn của bộ nhớ ảo? Chi phí thực hiện?
3. Các vấn đề của
bộ nhớ ảo: thay thế trang, cấp phát khung trang?
4. Mô hình working
set: khái niệm, cách tính trong thực tế, sử dụng?
7.6 Bài
Tập
Bài 1. Khi nào thì xảy ra lỗi trang? Mô tả xử lý của hệ điều
hành khi có lỗi trang.
Bài 2. Giả sử có một chuỗi truy xuất bộ nhớ có chiều dài p
với n số hiệu trang khác nhau xuất hiện trong chuỗi. Giả sử hệ thống sử
dụng m khung trang (khởi động trống). Với một thuật toán thay thế trang
bất kỳ:
- Cho biết số lượng tối thiểu các lỗi trang xảy ra?
- Cho biết số lượng tối đa các lỗi trang xảy ra?
Bài 3. Một máy tính 32-bit địa chỉ, sử dụng một bảng trang
nhị cấp. Địa chỉ ảo được phân bổ như sau: 9 bit dành cho bảng trang cấp 1, 11
bit cho bảng trang cấp 2, và cho offset. Cho biết kích thước một trang trong hệ
thống, và địa chỉ ảo có bao nhiêu trang?
Bài 4. Giả sử địa chỉ ảo 32-bit được phân tách thành 4
trường a,b,c,d. 3 trường đầu tiên được dùng cho bảng trang tam cấp,
trường thứ 4 dành cho offset. Số lượng trang có phụ thuộc vào cả kích thước 4
trường này không? Nếu không, những trường nào ảnh hưởng đến số lượng trang, và
những trường nào không?
Bài 5. Một máy tính có 48-bit địa chỉ ảo, và 32-bit địa chỉ
vật lý. Kích thước một trang là 8K. Có bao nhiêu phần tử trong một bảng trang (thông
thường)? Trong bảng trang nghịch đảo?
Bài 6. Một máy tính cung cấp cho người dùng một không gian
địa chỉ ảo 232 bytes. Máy tính này có bộ nhớ vật lý 218 bytes.
Bộ nhớ ảo được thực hiện với kỹ thuật phân trang, kích thước trang là 4096
bytes. Một tiến trình của người dùng phát sinh địa chỉ ảo 11123456. Giải thích
cách hệ thống chuyển đổi địa chỉ ảo này thành địa chỉ vật lý tương ứng. Phân
biệt các thao tác phần mềm và phần cứng.
Bài 7. Giả sử có một hệ thống sử dụng kỹ thuật phân trang
theo yêu cầu. Bảng trang được lưu trữ trong các thanh ghi. Để xử lý một lỗi
trang tốn 8 miliseconds nếu có sẵn một khung trang trống, hoặc trang bị thay
thế không bị sửa đổi nội dung, và tốn 20 miliseconds nếu trang bị thay thế bị
sửa đổi nội dung. Mỗi truy xuất bộ nhớ tốn 100nanoseconds. Giả sử trang bị thay
thế có xác suất bị sửa đổi là 70%. Tỷ lệ phát sinh lỗi trang phải là bao nhiêu
để có thể duy trì thời gian truy xuất bộ nhớ (effective acess time) không vượt
quá 200nanoseconds?
Bài 8. Xét các thuật toán thay thế trang sau đây. Xếp thứ tự
chúng dựa theo tỷ lệ phát sinh lỗi trang của chúng. Phân biệt các thuật toán
chịu đựng nghịch lý Belady và các thuật toán không bị nghịch lý này ảnh hưởng.
a)LRU
b)FIFO
c)Chiến lược thay thế tối ưu
d)Cơ hội thứ hai
Bài 9. Một máy tính có 4 khung trang. Thời điểm nạp, thời
điểm truy cập cuối cùng, và các bit reference (R), modify (M) của mỗi trang
trong bộ nhớ được cho trong bảng sau:
Trang
|
Nạp
|
Truy cập cuối
|
R
|
M
|
0
|
126
|
279
|
0
|
0
|
1
|
230
|
260
|
1
|
0
|
2
|
120
|
272
|
1
|
1
|
3
|
160
|
280
|
1
|
1
|
Trang nào sẽ được chọn thay thế theo:
a) Thuật toán NRU
b) Thuật toán FIFO
c) Thuật toán LRU
d) Thuật toán
"cơ hội thứ 2"
Bài 10. Xét mảng hai chiều A:
var A: array [1..100,
1..100] of integer;
Với A[1][1]
được lưu trữ tại vị trí 200, trong bộ nhớ tổ chức theo kỹ thuật phân trang với
kích thước trang là 200. Một tiến trình trong trang 0 (chiếm vị trí từ 0 đến
199) sẽ thao tác ma trận này; như vậy mỗi chỉ thị sẽ được nạp từ trang 0. Với 3
khung trang, có bao nhiêu lỗi trang sẽ phát sinh khi thực hiện vòng lặp sau đây
để khởi động mảng, sử dụng thuật toán thay thế LRU, và giả sử khung trang 1 chứa
tiến trình, hai khung trang còn lại được khởi động ở trạng thái trống:
a. for j: = 1 to
100 do
for i: =1 to 100
do A[i][j]: = 0;
b. for i: =1 to
100 do
for j: =1 to 100
do A[i][j]: = 0;
Bài 11. Xét chuỗi truy xuất bộ nhớ sau:
1, 2, 3, 4, 2, 1,
5, 6, 2, 1, 2, 3, 7, 6, 3, 2, 1, 2, 3, 6
Có bao nhiêu lỗi
trang xảy ra khi sử dụng các thuật toán thay thế sau đây, giả sử có 1, 2, 3, 4,
5, 6, 7 khung trang?
a) LRU
b) FIFO
c) Chiến lược tối
ưu
Bài 12. Trong một hệ thống sử dụng kỹ thuật phân trang theo
yêu cầu, xét hai đoạn chương trình sau đây:
const N = 1024*1024
var A,B: array [1..N] of integer;
[Program 1]
for i: =1 to N do
A[i]: =i;
for i: =1 to N do
B[A[i]]: =random(N);
[Program 2]
for i: =1 to N do
A[i]: = random(N);
for i: =1 to N do
B[A[i]]: =i;
Bài 13. Giả sử có một máy tính đồ chơi sử dụng 7-bit địa chỉ.
Kích thước một trang là 8 bytes, và hệ thống sử dụng một bảng trang nhị cấp,
dùng 2-bit làm chỉ mục đến bảng trang cấp 1, 2-bit làm chỉ mục đến bảng trang
cấp 2. Xét một tiến trình sử dụng các địa chỉ trong những phạm vi sau: 0..15,
21..29, 94..106, và 115..127.
b) Phải cấp phát cho tiến trình bao nhiêu khung trang,
giả sử tất cả đều nằm trong bộ nhớ chính?
c) Bao nhiêu bytes ứng với các vùng phân mảnh nội vi
trong tiến trình này?
d) Cần bao nhiêu bộ nhớ cho bảng trang của tiến trình
này?
Bài 14. Giả sử có một máy tính sử dụng 16-bit địa chỉ. Bộ nhớ
ảo được thực hiện với kỹ thuật phân đoạn kết hợp phân trang, kích thước tối đa
của một phân đoạn là 4096 bytes. Bộ nhớ vật lý được phân thành các khung trang
có kích thước 512 bytes.
a) Thể hiện cách
địa chỉ ảo được phân tích để phản ánh segment, page, offset.
b) Xét một tiến
trình sử dụng các miền địa chỉ sau, xác định số hiệu segment và số hiệu page
tương ứng trong segment mà chương trình truy cập đến:
350..1039,
3046..3904, 7100..9450, 33056..39200, 61230..63500
c) Bao nhiêu bytes
ứng với các vùng phân mảnh nội vi trong tiến trình này?
d) Cần bao nhiêu
bộ nhớ cho bảng phân đoạn và bảng trang của tiến trình này?
[He Dieu Hanh] Chương 7. Bộ nhớ ảo
Reviewed by Nguyen Nam
on
4/18/2014
Rating:
Không có nhận xét nào: