Tìm Hiểu Về Kiến Trúc MIPS: Vi Xử Lý RISC Tiên Phong

MIPS, viết tắt của Microprocessor without Interlocked Pipeline Stages (Vi xử lý không có các giai đoạn đường ống liên động), là một kiến trúc tập lệnh RISC (Reduced Instruction Set Computing) được phát triển bởi MIPS Technologies. Ban đầu, kiến trúc MIPS là 32-bit, sau đó phát triển lên phiên bản 64-bit. Trải qua nhiều sửa đổi, bao gồm MIPS I, MIPS II, MIPS III, MIPS IV, MIPS V, MIPS32 và MIPS64, phiên bản hiện tại là MIPS32 và MIPS64. Một số tùy chọn mở rộng khác bao gồm MIPS-3D (bộ tập lệnh SIMD), MIPS16e (nén vi lệnh để giảm dung lượng chương trình), và MIPS MT (xử lý đa luồng). Kiến trúc MIPS thường được nghiên cứu trong các khóa học kiến trúc máy tính tại các trường đại học và có ảnh hưởng lớn đến các kiến trúc RISC sau này, ví dụ như Alpha.

Lịch Sử Phát Triển Của MIPS

Người Tiên Phong Của Kiến Trúc RISC

Năm 1981, một nhóm nghiên cứu do John L. Hennessy dẫn đầu tại Đại học Stanford bắt đầu phát triển bộ vi xử lý MIPS đầu tiên. Ý tưởng cốt lõi là tăng hiệu năng thông qua việc sử dụng “ống vi lệnh” (instruction pipeline) sâu. Kỹ thuật đường ống đã được biết đến trước đó, nhưng chưa được khai thác một cách triệt để. CPU được xây dựng từ các đơn vị riêng biệt như giải mã vi lệnh, ALU (Arithmetic Logic Unit – đơn vị tính toán số học và logic), tải và lưu trữ dữ liệu, cùng nhiều thành phần khác.

Trong các thiết kế truyền thống, một vi lệnh cụ thể trong chương trình phải hoàn thành trước khi vi lệnh tiếp theo được thực thi. Tuy nhiên, trong kiến trúc đường ống, các vi lệnh có thể được xử lý song song. Ví dụ, trong khi một vi lệnh toán học đang được xử lý trong bộ vi xử lý dấu phẩy động, thì đơn vị tải/lưu trữ có thể đồng thời lấy vi lệnh tiếp theo.

Một rào cản quan trọng đối với đường ống là một số vi lệnh, chẳng hạn như phép chia, cần nhiều thời gian để hoàn thành. Do đó, CPU phải chờ trước khi đưa vi lệnh tiếp theo vào đường ống. Một giải pháp cho vấn đề này là sử dụng một loạt các “liên khóa” (interlock) để xác định giai đoạn nào đang bận và tạm dừng các giai đoạn khác. Nhóm của Hennessy nhận thấy rằng các liên khóa là một trở ngại lớn, vì việc liên lạc giữa tất cả các mô-đun trong CPU tốn thời gian và làm giảm tốc độ xung nhịp.

Một khía cạnh khác của thiết kế MIPS là nó thực hiện một pha nhỏ, bao gồm truy xuất cache, của tất cả các vi lệnh trong một chu kỳ, loại bỏ sự cần thiết của các liên khóa và cho phép một chu kỳ thông suốt. Mặc dù thiết kế này loại bỏ một số vi lệnh hữu ích như nhân và chia, nhưng hiệu năng tổng thể của hệ thống được cải thiện đáng kể vì chip có thể chạy với tốc độ xung nhịp cao hơn. Việc liên khóa có thể ảnh hưởng đến tốc độ của đường ống, cũng như thời gian cần thiết để thiết lập khóa.

Sự khác biệt giữa thiết kế MIPS và đối thủ Berkeley RISC nằm ở cách xử lý các hàm con (subroutine). RISC sử dụng kỹ thuật “thanh ghi cửa sổ” (register windowing) để cải thiện hiệu năng của các tác vụ phổ biến, nhưng giới hạn số lượng mức nhảy tối đa. Mỗi lần gọi tiểu hàm cần tập hợp thanh ghi riêng, đòi hỏi tài nguyên thanh ghi. Hennessy cho rằng trình biên dịch thông minh có thể tìm thấy các thanh ghi trống mà không cần sắp xếp lại. Việc tăng số lượng thanh ghi không chỉ đơn giản hóa quá trình này mà còn tăng hiệu năng tổng thể của tác vụ.

Mặt khác, thiết kế MIPS rất giống với thiết kế RISC điển hình. Để tiết kiệm bit trong vi lệnh, thiết kế RISC giảm số lượng vi lệnh. Thiết kế MIPS sử dụng 6 bit trong số 32 bit cho vi lệnh cơ bản; 26 bit còn lại là địa chỉ nhảy hoặc sử dụng trường 5 bit để chỉ định tối đa 3 thanh ghi với giá trị dịch kết hợp với 6 bit vi lệnh. Một định dạng khác sử dụng 3 thanh ghi với một giá trị 16 bit mã trong vi lệnh. Một định dạng khác nữa là 6 bit thanh ghi, 4 bit vi lệnh.

Cách mã hóa này tăng số lượng thanh ghi lên 64 thanh ghi. Số lượng chỉ lệnh tùy thuộc vào cách mã hóa, thông thường lên tới hơn 100 chỉ lệnh.

Phần Cứng Đầu Tiên

Năm 1984, Hennessy nhận thấy tiềm năng thương mại của thiết kế và rời Stanford để thành lập MIPS Computer System. Họ cho ra mắt thiết kế đầu tiên, R2000, vào năm 1985, và cải tiến kiến trúc với R3000 vào năm 1988. Những CPU 32-bit này đã thiết lập nền tảng cho công ty trong suốt những năm 1980, được sử dụng chủ yếu trong dòng máy trạm SGI. Tuy nhiên, thiết kế thương mại này khác với nghiên cứu lý thuyết tại Stanford vì nó tích hợp hầu hết các liên khóa trong phần cứng, cung cấp đầy đủ các vi lệnh nhân và chia.

Năm 1991, MIPS giới thiệu vi xử lý 64-bit đầu tiên, R4000. R4000 là một bước tiến lớn về TLB (Translation Lookaside Buffer), mỗi mục không chỉ chứa địa chỉ ảo mà còn cả ID không gian địa chỉ ảo. Bộ đệm này loại bỏ vấn đề hiệu năng chính của vi hạt nhân (microkernel), vốn sẽ chậm trên các kiến trúc đối thủ (Pentium, PowerPC) do cần thiết phải xóa TLB khi chuyển đổi thường xuyên.

Tuy nhiên, MIPS gặp khó khăn về tài chính để đưa sản phẩm ra thị trường. Kiến trúc này thực sự quan trọng đối với SGI, vào thời điểm đó là một trong những khách hàng của MIPS. SGI đã mua lại công ty vào năm 1992 để đảm bảo kiến trúc không bị mất. Với tư cách là công ty con của SGI, công ty này được biết đến với tên gọi MIPS Technologies.

Chip MIPS R4000, vi xử lý 64-bit đầu tiên của MIPS Technologies.

Sự Tổng Hợp Nhân

Trong những năm gần đây, hầu hết công nghệ được sử dụng trong các thế hệ MIPS đã cung cấp sở hữu trí tuệ nhân (IP core) cho thiết kế nhúng. Cả lõi cơ bản 32-bit lẫn 64-bit đều được cung cấp, được biết đến với tên gọi 4k và 5k. Những lõi này được thêm vào nhiều đơn vị khác như dấu phẩy động, SIMD, và rất nhiều thiết bị xuất/nhập khác.

Hợp Ngữ MIPS

Trong MIPS, có 32 thanh ghi, dữ liệu phải nằm trong thanh ghi để có thể xử lý (thanh ghi – thanh ghi).

  • d, t và s là ký tự chỉ thanh ghi.
  • C có nghĩa là hằng số (được mã hóa trong vi lệnh).
  • Gạch ngang (-) có nghĩa là không xác định.

MIPS có vài chục chỉ lệnh.

Loại vi lệnh Tên Mô tả Hợp ngữ Ý nghĩa Định dạng Mã vi lệnh
Tính toán Cộng add $d,$s,$t $d=$s+$t r 2016
Cộng hai thanh ghi, kích hoạt bẫy nếu tràn bit 000000ssssstttttdddd--10000
Cộng không dấu addu $d,$s,$t
Trừ sub
Trừ không dấu subu
Cộng hằng số addi
Cộng hằng số không dấu addiu
Nhân mult
Chia div
Chia không dấu divu
Truyền dữ liệu Load double word ld $t,C($s)
Load word lw $t,C($s)
Load halfword unsigned
Load byte lb
Load byte unsigned lbu
Store double word sd
Store word sw
Store half
Store byte
Store upper
Load upper
Load upper immediate
Move from high
Move from low
Move from Control Register

Tham Khảo