Tin học
Bạn có muốn phản ứng với tin nhắn này? Vui lòng đăng ký diễn đàn trong một vài cú nhấp chuột hoặc đăng nhập để tiếp tục.

RISC và CISC

Go down

RISC và CISC Empty RISC và CISC

Bài gửi  lengocthuthao89 (i11c) 13/9/2011, 01:16

1. RISC có những gì ?
RISC là viết tắt của “reduced instruction set computer”, với gợi ý là máy tính (hay là bộ vi xử lý bên trong nó) đã được giảm nhỏ tập lệnh. Nó giống như là CPU Lite. Hay bạn có thể nói thô thiển là: đó là một dạng thu nhỏ (cắt giảm) của một con vi xử lý, có thể bạn nói đúng một phần nào đó.
Triết lý cho phát triển RISC đó là cắt giảm bộ vi xử lý để chỉ còn lại những bộ phận thiết yếu của nó. Những gì không thực sự cần thiết sẽ bị vứt bỏ. Với các nhà lập trình thì đó có nghĩa là các chíp RISC thường không thể thực hiện một phép nhân đơn giản. Lý thuyết của phép nhân là thực hiện liên tiếp nhiều phép cộng, do đó lệnh ADD là đủ.
Một ý khác của RISC đó là các chức năng phức tạp thích hợp thực hiện bằng phần mềm hơn là bằng phần cứng. Phần mềm thì dễ thay đổi, dễ cập nhật, và tạo ra nhanh hơn. Viết mã mới nhanh hơn là thiết kế và xây dựng một chíp mới. Do đó các máy tính dựa trên RISC có thể được nâng cấp nhanh hơn. Các chương trình và các thuật toán có thể điều chỉnh và cải tiến. Tốt nhất là phần cứng RISC phải được đơn giản hóa, tối ưu hóa sao cho nó chạy nhanh hơn.
Đúng là lúc đầu các chíp RISC nhỏ hơn, đơn giản hơn, và nhanh hơn so với các chíp CISC vào thời điểm đó. Vứt bỏ các trang bị thừa mứa mà các dòng vi xử lý như 68020 và 80286 đã tích lũy, các dòng RISC cạnh tranh như SPARC và MIPS trở nên nhanh hơn nhiều. Nếu xét về tốc độ rõ ràng là RISC là người chiến thắng. Các tạp chí kỹ thuật và các xuất bản thương mại tới tấp quảng cáo sâu rộng RISC như là một lĩnh vực mới cho máy tính. Tất cả các vi xử lý quen thuộc trước kia dường như kiệt quệ.
Dòng vi xử lý 68K tốc độ xung nhịp chỉ khoảng 66 MHz, trong khi đó với các dòng kia thì tốc độ xung nhịp tính bằng 3 con số. Ngay cả bây giờ cũng vậy, hầu hết các vi xử lý 68K tốc độ chỉ dưới 100 MHz. Phải chăng dòng vi xử lý CISC sắp chết và không thể dùng cho các ứng dụng hiện đại ?
Dù thấp hơn về tốc độ xung nhịp, các chíp CISC như 68K và x86 vẫn cho hiệu suất ngang bằng, và có thể cao hơn so với các đối thủ RISC. Chúng đáng xem xét hơn và thường là sự lựa chọn tốt nhất cho nhiều hệ thống nhúng. Dù được gán nhãn chói lọi RISC thường là sự lựa chọn tệ hại cho các ứng dụng real-world.
2. Tốt và xấu
Những gì bạn nhận được từ kiến trúc RISC đó là một CPU khá đơn giản, với tập lệnh dễ hiểu và trực quan. Tất cả các lệnh có cùng chiều dài, điều này làm cho chúng dễ dàng xắp xếp gọn gàng trong RAM. Chúng cũng có cách mã hóa tương tự nhau, do đó nếu bạn có ý định dịch ngược opcode của RISC thì cũng dễ thực hiện. Cũng dễ dàng đếm số lệnh trong bộ nhớ. Và cuối cùng rất dễ tính toán số chu kỳ máy thực hiện cho một đoạn chương trình, bởi vì các lệnh của RISC hầu hết đều thực hiện trong một chu kỳ máy. Chỉ cần đếm số lệnh (hoặc số byte, đem chia cho 4) và bạn có kết quả, dĩ nhiên là tạm loại trừ ảnh hưởng của cache và các trạng thái chờ.
RISC là những gì thực hiện bằng hoặc không bằng tập lệnh, hoặc các tính năng khác mà bạn muốn. Trước tiên là về toán học. Hầu hết các chíp RISC trước kia không có lệnh nhân và cũng không có lệnh chia. Ngày nay hầu hết vẫn không có lệnh chia. Nếu bạn là người lập trình bằng hợp ngữ thì xin chúc mừng, bạn phải tự viết các hàm thực hiện phép nhân và phép chia số nguyên. Đừng nghĩ đến phép toán dấu chấm động, hầu hết các chíp RISC không hỗ trợ điều này. Công bằng thì hầu hết các chíp CISC cũng chẳng có các bộ FPU, nhưng FPU phổ biến trong các bộ vi xử lý CISC loại cũ nhiều hơn là trong các chíp RISC mới.
Bạn cũng chẳng có các phép toán trực tiếp trên bít. Ví dụ, để kiểm tra và đảo một bít trong một thanh ghi trạng thái, bạn phải đọc toàn bộ nội dung của thanh ghi vào bên trong vi xử lý. Rồi che các bít mà bạn không sử dụng, dịch phải kết quả, kiểm tra trạng thái của bít, đảo bít dùng phép exclusive-OR, dịch trái nó trở lại vị trí cũ, rồi ghi nó trở ra thanh ghi.
Truy cập bộ nhớ không xắp xếp cũng là phần bị bỏ đi trong RISC. Các chíp RISC đã được thiết kế cho các trạm làm việc, nơi mà dữ liệu luôn được xắp xếp theo từ (word) bởi vì trình biên dịch đặt chúng nằm như thế. Lượng dữ liệu nhỏ hơn (như byte) hoặc là không tồn tại hoặc là được chèn thêm zero để vừa với một từ 32 bít. Trong các hệ thống nhúng hiếm khi có sự ngăn nắp như vậy.
Một số 32 bít được lưu ở một địa chỉ lẻ sẽ không thể truy cập được bởi nhiều chíp RISC. Chúng không thể xử lý được các toán hạng không xắp xếp (?). Tương tự như vậy, lượng dữ liệu lẻ, như giá trị 24 bít phải được mở rộng zero- hoặc sign- khi lưu trữ chúng, và như thế là lãng phí RAM.
Có một tin tốt đó là trình biên dịch đã xử lý điều này. Nếu bạn là người lập trình bằng hợp ngữ, RISC sẽ là sự đau khổ. Nếu bạn lập trình bằng C hoặc là một ngôn ngữ cấp cao nào đó thì bạn không cần để ý đến các giới hạn này. Trừ khi bạn quan tâm đến mật độ mã.
3. Mật độ mã
Dĩ nhiên kích thước mã không quan trọng. Trừ khi bạn là một nhà lập trình nhúng hoặc là một kỹ sư, và bạn phải nhét 10k mã vào trong một chíp chỉ có 5k mã, khi đó ép kích thước mã xuống là một vấn đề lớn. Nhiều nhà thiết kế hệ nhúng đã đổ nhiều tiền vào RAM và ROM của hệ thống hơn là vào bộ vi xử lý. Bộ nhớ xác định (hay là giới hạn) đặt điểm của nhiều hệ thống. Nếu các nhà lập trình không thể đặt vừa mã vào bộ nhớ thì coi như xong.
Khi đó mật độ mã trở thành một vấn đề lớn. Mật độ mã mô tả mã thực thi của một chương trình được đóng gói chặt chẽ đến mức nào, và nó khác nhau đáng kể giữa các dòng vi xử lý. Nếu bạn không có kinh nghiệm về điều này, bạn có thể nghĩ rằng trình một chương trình C đã được biên dịch thì thực thi trên con chíp nào cũng như nhau. Đó là sai lầm lớn.
Cùng một chương trình C biên dịch cho các chíp khác nhau sẽ cho ra memory footprint hoàn toàn khác nhau. Đó không phải là lỗi hay là khuyết điểm của trình biên dịch. Đó là đặc điểm tự nhiên của các CPU. Và RISC thì cũng như thế.
Hình 1 cho thấy mật độ mã của một số vi xử lý phổ biến. Như bạn thấy sự khác nhau có thể lên đến mức 2:1. Ngay cả khi các chíp này thực thi cùng một chương trình (có nghĩa là có cũng mã nguồn) và tạo ra cùng một kết quả, thì mã trên chíp này vẫn có thể ít hơn một nửa so với chíp kia. Đó là mật độ mã.
Bạn cũng có thể thấy rằng các chíp CISC có mật độ mã tốt hơn so với các chíp RISC. Nhớ là nguyên lý chủ đạo của RISC đó là phần cứng phải đơn giản, tất cả các hoạt động phức tạp được thực hiện bằng phần mềm. Điều đó có nghĩa là chíp RISC của bạn sẽ cần nhiều phần mềm hơn để thực hiện cùng một công việc. Hầu hết các chíp RISC không có lệnh chia. Nếu bạn muốn chia 2 số bạn phải hiện bằng phần mềm.
Trình biên dịch phải làm việc bằng tập lệnh mà phần cứng đã cho. Nếu vi xử lý có tập lệnh nhỏ trình biên dịch phải bù lại bằng cách tạo ra nhiều phần mềm.

4. Nén mã
Một lý do khác mà các chíp CISC có mật độ mã tốt hơn đó là bởi vì chúng tập lệnh có xu hướng được làm ngắn hơn. Theo định nghĩa các chíp RISC 32-bit phải có tập lệnh 32-bit. Còn một chíp CISC 32-bit thì lại khác, có thể có lệnh 8-bit, 16-bit, 32-bit và có cả các lệnh dài hơn nữa. Đây là một trong những đặc điểm làm cho chíp CISC phức tạp, nhưng điều đó cũng làm cho nó thực tế hơn trong các hệ thống nhúng.
Tại sao bạn quan tâm đến số bít của tập lệnh ? Bởi vì trong khi một con 68020 có thể đặt vừa một lệnh ADD vào chỉ 8 bít của bộ nhớ chương trình thì một con MIPS R400 lại cần đến 32 bit, như thế là bạn đã ném đi 3/4 bộ nhớ quý giá cho mỗi lần chương trình thực hiện cộng hai số với nhau. Và chíp MIPS không thể cộng nhanh hơn chíp 68K, do đó bạn cũng chẳng được gì hơn ngoài lời nói bạn đang sở hữu một hệ thống RISC.
Trong thời gian gần đây một số nhà sản xuất RISC đã đưa ra giải pháp thông minh để giải quyết vấn đề này. Giải pháp này thường được gọi là nén mã, nhưng đó chỉ là sự dùng từ sai. Không có sự nén mã thực sự, giống như PKZIP. Họ chỉ thay đổi tập lệnh của chíp một ít sao cho không phải tất cả các lệnh đều dài 32 bít.
3 ví dụ chính cho vấn đề này đó là ARM, ARC Cores và MIPS. Chúng có các phiên bản nén mã với các tên gọi tương ứng là Thumb, ARCompact và MIPS-16. Chúng đều thêm một số lệnh 16-bit vào tập lệnh 32-bit. Trình biên dịch C của chúng bây giờ có thể lựa chọn dùng các lệnh 16-bit để làm cho mã thực thi nhỏ hơn.
Nhỏ hơn bao nhiêu tùy thuộc vào nhiều thứ. Và như bạn đã thấy, tiếp thị bằng cách thổi phồng chẳng bao giờ dễ cả. Tuy nhiên trong các thử nghiệm thực tế độ nén trung bình khoảng 20% đến 30% và tùy thuộc vào chương trình. Nhắc bạn rằng đó chỉ là sự nén của không gian mã, vùng dữ liệu không được nén. Tuy nhiên đó vẫn là một hướng đúng để làm cho kiến trúc RISC hấp dẫn hơn những gì mà chúng đã có.
Trong hai trường hợp (ARM Thumb và MIPS MIPS-16) mã thực thi phải xác định rõ ràng giữa chế độ 32-bit và 16-bit. Bạn không thể trộn lẫn hai loại lệnh này với nhau, do đó bạn phải cách ly đoạn mã chạy bằng các phép toán 16-bit ra khỏi đoạn mã chạy bằng các lệnh 32-bit.
Bạn thấy đấy, cân bằng giữa tập lệnh ngắn hơn là sự giới hạn của nó. Ví dụ, mã 16-bit không thể xử lý ngắt, quản lý cache, quản lý bộ nhớ, hoặc nhảy. May mắn là trình biên dịch cho Thumb và MIPS-16 đã loại trừ các vấn đề này. ARCompact của ARC không có sự giới hạn này bởi vì nó không chuyển đổi giữa hai chế độ. Nó trộn lẫn cả hai kích thước, do đó bạn không phải vất vả tách rời chương trình của bạn.
Một điểm khác nữa, cách giải quyết của IBM cho các chíp PowerPC nhúng đó là CodePack. Không như các tập lệnh nén khác, IBM thực sự nén mã nhị phân thực thi của nó, giống như là sử dụng PKZIP để nén vậy. Bạn nén chương trình sau khi compliled, assembled và linked. Rồi lưu phiên bản được nén này vào ROM hoặc đĩa. Chắc chắn là các chíp PowerPC nhúng phải có thêm phần cứng để giải nén và ném chúng vào bộ nhớ.
Thứ nhất sẽ hoàn toàn không dò được mã, bởi vì nó không được lưu trữ theo định dạng mã thông thường. Mã đã bị nén điều này làm cho nó khó bị disassemble. Đó có thể là một thuận lợi nếu bạn muốn bảo vệ mã khỏi những cặp mắt tò mò. CodePack mã hóa phần mềm hiệu quả như nén phần mềm vậy.
Thứ hai, bởi vì phải giải nén phần mềm khi đang thực thi, đôi khi có thể mất thời gian lâu hơn dự đoán. Việc xử lý lệnh rẽ nhánh và nhảy thực sự phải khéo léo, bởi vì đích của lệnh rẽ, sẽ không dễ dàng xác định được khi nó bị mã hóa, có thể nằm đâu đó trong ROM.
Thứ 3, với mỗi chương trình CodePack dùng một chìa khóa nén riêng do đó các chương trình khác nhau sẽ nén hoàn toàn khác nhau. Điều đó có nghĩa là mã nhị phân đã nén không thể thực thi được trên một chíp PowerPC khác trừ khi bạn cung cấp chìa khóa.
Cuối cùng, CodePack có cùng hệ số nén 30% như ARC, ARM và MIPS. Với tất cả độ phức tạp của nó, nó chẳng tốt hơn đáng kể. Tuy nhiên cũng đáng khâm phục IBM bởi vì họ đã đưa ra vài thứ hoàn toàn khác.
5. Năng lượng cho RISC
Một trong những thuận lợi của các chíp RISC là chúng có sự tiêu thụ năng lượng thấp. Như một luật lệ các chíp RISC dùng ít năng lượng hơn nhiều so với CISC. Điều này là rõ ràng: thiết kế của vi xử lý RISC là đơn giản hơn và hợp lý hơn thì phải dùng năng lượng ít hơn.
Điểm này rất quan trọng nếu bạn đang làm các smart card, thermostat, hoặc cell phone.
Mật độ mã đóng một vai trò trong tiêu thụ năng lượng, do đó chíp có mật độ mã tốt hơn có thể sử dụng ít năng lượng hơn bởi vì chúng không cần mất nhiều thời gian để truy cập bộ nhớ. Mỗi lần tìm nạp ROM hoặc đọc/ghi RAM sẽ tiêu thụ một ít năng lượng. Càng giảm thiểu điều này thì càng tốt. Có thể nói rằng tăng 2 lần mật độ mã là tăng 2 lần tiêu thụ năng lượng.

6. Hiệu suất
Hiệu suất là một vấn đề lớn mà ai cũng nhắm tới. Hiệu suất tốt hơn là một trong những lợi ích chính của RISC, do đó mà các chíp RISC luôn nhanh hơn, đúng không ? Không !
Cuộc đua giữa các vi điều khiển không đơn giản, bởi vì mọi người quan tâm đến các loại hiệu suất khác nhau. Ví dụ, chíp nào tốt cho xử lý media có thể không tốt cho xử lý mạng. Thế đủ để nói rằng không có một vi xử lý nào xuất sắc về mọi mặt. Mỗi tập lệnh CPU là một sự thỏa hiệp.
Bạn phải chọn một CPU với kiến trúc tập lệnh (instruction set architecture – ISA) phù hợp với ứng dụng thực tế của bạn. Hai chíp chạy cùng tốc độ (ví dụ 100 MHz) có thể cho hiệu suất hoàn toàn khác nhau bởi vì sự khác nhau trong ISA. Đó là lý do tại sao các nhà sản xuất vẫn tiếp tục điều chỉnh tập lệnh, và đó cũng là lý do tại sao các dòng CPU mới có tập lệnh do chính người sử dụng định nghĩa đang được mọi người ưa chuộng.
Đa số các tập lệnh của RISC đều như nhau, tưởng chừng như chúng chỉ hỗ trợ những vấn đề thiết yếu ? Thực tế thì mỗi kiến trúc RISC đều đang dần thay đổi mà không bám chặt vào đường lối RISC trước kia. Tuy nhiên đánh giá gần đúng thì các chíp RISC đều có điểm chung và có thể thay thế cho nhau.
Với CISC thì khác, chúng có tập lệnh đầy đủ, có thể hoặc rất hữu dụng hoặc hoàn toàn không phù hợp cho hệ thống của bạn. Đôi khi bạn tự hỏi ở đâu chui ra các tập lệnh kỳ quặc như thế, các nhà lập trình sử dụng các tập lệnh đó vào việc gì. Khi khác bạn lại tự hỏi bạn phải xoay xở làm sao nếu không có các tập lệnh như thế.
Một trong các lệnh mà tôi thích là lệnh TBLS ở dòng chíp 68300 của Motorola. TBLS là một lệnh tra bảng và nội suy (table look up and interpolate instruction). Hầu hết các nhà lập trình sẽ chẳng bao giờ dùng nhưng nó sẽ cứu đời bạn khi bạn cần đến nó.
Tập TBLS cho phép bạn tạo ra một hàm hình học phức tạp từ một bảng các điểm dữ liệu rời rạc. TBLS tìm kiếm trong bảng giá trị mà bạn đã tạo ra, xác định hai số gần nhất với số mà bạn chỉ định. Sau đó thông qua phép nội suy tuyến tính nó chỉ ra chính xác giá trị nằm giữa hai số kia. Thực chất TBLS nối hai điểm trong đồ thị các điểm x, y rời rạc, trả về giá trị y từ giá trị x như ở hình 2.
Khá lạ, bạn nghĩ thế ? Nhưng nó rất cần thiết nếu bạn đang làm điều khiển chuyển động. Nó giúp thay thế hàng trăm dòng lệnh nếu dùng các hàm xử lý hình học thông thường với tất cả các trường hợp biệt lệ và các điều kiện biên khác nhau. Nhớ là TBLS là một lệnh đơn thực hiện chỉ mất khoảng 30 chu kỳ xung nhịp.

7. Lời kết
Tóm lại RISC cung cấp các chức năng để có được tốc độ xung nhịp nhanh hơn. Nếu bạn ưa tốc độ và tốc độ xung nhịp là thứ mà bạn cần thì hãy dùng nó. Bạn sẽ có tốc độ xung nhịp cao hơn bằng cách dùng một vi xử lý 200 MHz thay vì dùng một con 75 MHz.
Tuy nhiên có thể bạn không có được hiệu suất tốt hơn, và chắc chắn là sẽ phải bỏ ra nhiều tiền hơn. Một bộ vi xử lý nhanh cần phải có một RAM nhanh, một ROM nhanh, và I/O nhanh. Kiến trúc bus cũng phải nhanh hơn. Và cache sẽ đóng vai trò lớn trong hiệu suất khi mà tốc độ đó dùng đến 90% thời gian quý báu của nó để truy xuất cache.
Không thể phủ nhận khả năng của RISC. Nó được hiểu như là một con đường đi tới mới, đầy hứng thú. Cũng thật khác thường là các vi xử lý CISC vẫn tiếp tục phát triển mạnh. Mật độ mã và khả năng tích hợp của chúng tốt hơn, và chúng cho hiệu suất tốt hơn bằng các lệnh hỗ trợ bit manipulation, memory accesses, looping, decision trees,… Đôi khi chậm và chắc mới thật sự thắng trong cuộc đua.

lengocthuthao89 (i11c)

Tổng số bài gửi : 50
Join date : 13/09/2011

Về Đầu Trang Go down

Về Đầu Trang

- Similar topics

 
Permissions in this forum:
Bạn không có quyền trả lời bài viết