LRU cache: get/put với thay thế phần tử lâu chưa dùng nhất
Class cần viết: lru_cache · cần máy chấm có SystemVerilog · 7 case (2 mẫu) · giới hạn 4 s/case · ~35 phút
LRU (least recently used) là chính sách thay thế của cache, TLB và page table: khi đầy, bỏ phần tử lâu nhất chưa được dùng. Đây là câu phỏng vấn thuật toán kinh điển (LeetCode 146). Với kỹ sư DV, nó còn là mô hình tham chiếu cần viết khi verify một cache thật. Bài này viết nó bằng các cấu trúc dữ liệu của SystemVerilog.
class lru_cache;
int evictions; // số phần tử đã bị loại
function new(int cap); // dung lượng ≥ 1
function bit get(int key, output int val); // trúng: val = giá trị, trả 1, khoá thành "mới dùng nhất";
// trượt: val = 0, trả 0
function void put(int key, int val); // khoá đã có: cập nhật giá trị, khoá thành mới dùng nhất;
// khoá mới: thêm vào; nếu vượt dung lượng thì loại khoá lâu chưa dùng nhất
function int size();
function bit contains(int key); // chỉ hỏi: KHÔNG tính là dùng
endclass
Ví dụ, dung lượng 2:
| Lệnh | Kết quả | Thứ tự (lâu → mới) |
|---|---|---|
put(1, 10) |
1 | |
put(2, 20) |
1, 2 | |
get(1) |
10 | 2, 1 |
put(3, 30) |
loại 2 | 1, 3 |
get(2) |
trượt | 1, 3 |
put(1, 11) |
cập nhật | 3, 1 |
Các case
- put rồi get, chưa đầymẫu
- Đầy: loại phần tử lâu chưa dùng nhấtmẫu
Cùng 5 case ẩn kiểm các yêu cầu còn lại của đề. Case ẩn chỉ báo đúng/sai, không nói chi tiết: tự tìm chỗ sai từ đề, hoặc mở gợi ý.
Testbench có mô hình tham chiếu riêng, độc lập với lời giải mẫu. Lời giải mẫu đã chạy qua mọi case trên simulator thật, và 4 bản lỗi mẫu đều bị ít nhất một case bắt. Case mẫu sai sẽ cho biết chỗ sai đầu tiên (giá trị mong đợi so với giá trị nhận được); case ẩn chỉ báo đúng/sai.