6.3.1.1 Song song mức lệnh
Với kiến trúc song song mức lệnh sốlượng song song có thể trong một khối cơ bản, các dòng lệnh tuần tự không có rẽ nhãnh ngoại trừđầu vào và các rẽnhánh rạ Đối với các chương trình MIPS bình thường thì tần suất các nhánh động thường từ15% đến 25%, có nghĩa là từ bốn đến bảy lệnh được thực hiện giữa hai lệnh rẽ nhánh. Vì các lệnh này khá phụ thuộc vào các lệnh khác và số lượng gối lên nhau mà chúng ta có thể tận dụng trong một khối cơ bản có vẻ ít hơn nhiều so với kích thức trung bình của khối cơ bản. Để đạt được sựtăng hiệu năng đáng kể, chúng ta phải tận dụng ILP (Instruction Level Parallelism) trên nhiều khối cơ bản. Cách đơn giản và phổ biến nhất đểtăng sốlượng song song có thể giữa các lệnh là tận dụng song song giữa các lần lặp. Kiểu song song này gọi là song song mức lặp (loop-level). Đây là một ví dụ đơn giản về một vòng lặp dùng để cộng hai mảng 1000 phần tửvà được thực hiện song song hoàn toàn: tất cảcác bước lặp của vòng lặp có thểđược gối lên nhau với các bước lặp khác mặc dùng trong một bước lặp các lệnh khó có thể gối lên nhaụ
for (i=1; i<=1000; i=i+1) x[i] = x[i] + y[i];
Có một số kỹ thuật mà chúng ta sẽ xem xét để chuyển đổi song song mức lặp thành song song mức lệnh. Vềcơ bản, các kỹ thuật này hoạt động bằng cách trải các vòng lặp ra hoặc theo cách tĩnh bởi chương trình dịch hoặc theo cách động bởi phần cứng. Một phương pháp thay thế quan trọng để tận dụng song song mức lặp là sử dụng các lệnh vector. Vềcơ bản, một lệnh vector hoạt động dựa trên một chuỗi các mục dữ liệụ Các bộ xử lý có tận dụng ILP phần lớn đã thay thế các bộ xử lý dựa trên vector. Tuy nhiên, các tập lệnh vector có thểđược sử dụng lại, ít nhất là trong các xửlý đồ họa, xử lý tín hiệu số, và các ứng dụng đa phương tiện.
6.3.1.2 Kiến trúc song song mức luồng
Với một bộ vi xử lý có nhiều luồng mã lệnh và nhiều luồng dữ liệu, mỗi một bộ vi xử lý có thể chạy các lệnh của chính nó. Trong nhiều trường hợp, các vi xử lý có thể chạy các tiến trình khác nhau (một tiến trình trên một bộ vi xử lý là một đoạn mã có thể chạy độc lập và các trạng thái của tiến trình có chứa toàn bộ các thông tin cần thiết cho việc chạy chương trình trên bộ vi xửlý đó). Trong một môi trường nhiều chương trình, nơi mà các bộ vi xử lý có thểđảm nhận các công việc của riêng nó, mỗi tiến trình trên một bộ vi xử lý là hoàn toàn độc lập với các tiến trình khác trên các bộ vi xử lý khác.
Chúng ta nhận thấy rằng thật là hữu ích nếu có thể chạy một chương trình trên một bộ đa xử lý, chia sẻ mã lệnh và hầu hết các không gian địa chỉ của nó. Khi có nhiều tiến trình cùng chia sẻ mã lệnh và dữ liệu theo kiểu này, chúng được gọi là các luồng. Ngày nay, thuật ngữ luồng thường được dùng để chỉ việc tiến hành chạy mã trên nhiều vùng, có
thể là trên nhiều vi xử lý khác nhau, ngay cả khi chúng không chia sẻkhông gian địa chỉ. Để có thể tận dụng hiệu năng của một bộ đa xử lý có n vi xử lý, chúng ta cần phải có tổi thiểu là n luồng hoặc n tiến trình chạy đồng thờị Các tiến trình độc lập có thể là do lập trình viên xác định tại thời điểm lập trình hoặc có thểđược tạo lập bởi trình biên dịch. Vì rằng khái niệm song song trong trường hợp này được bao hàm trong các luồng nên được gọi là xử lý song song mức luồng.
Xử lý song song song cho phép các luồng có thể chia sẻcác đơn vị chức năng của một bộ vi xửlý đơn theo kiểu xếp chồng. Để có thể cho phép chia sẻcác đơn vị này, bộ vi xử lý cần thiết phải nhân đôi trạng thái độc lập của mỗi luồng. Ví dụ là phải có một bản copy riêng biệt cho file đăng ký, một PC riêng biệt và một bảng phân trang cho mỗi luồng. Bộ nhớ có thểđược chia sẻthông qua cơ chế bộ nhớ ảo, cơ chếnày đã hỗ trợ lập trình đa luồng. Thêm vào đó, phần cứng phải hỗ trợ khảnăng thay đổi tới các luồng khác nhau đủ nhanh; trong thực tế, cơ chế chuyển luồng phải nhanh hơn cơ chế chuyển tiến trình, và thông thường, cơ chếnày đòi hỏi hàng trăm tới hàng ngàn chu kỳ vi xử lý.
Có hai cách tiếp cận tới xửlý đa luồng. Đó là: chuyển mạch đa luồng mịn giữa các luồng (Fine-grained multithreading switch) trên mỗi lệnh, làm cho việc chạy các luồng được tiến hành luân phiên. Việc chạy luân phiên này được thực hiện thông qua cơ chế xoay vòng, bỏ qua mọi luồng bị giữ tại thời điểm đó. Để có thể thực hiện đa luồng theo kiểu này, khối xử lý trung tâm phải có thể chuyển giữa các luồng trong mọi chu kỳđồng hồ. Một lợi điểm quan trọng của chuyển mạch đa luồng mịn là nó thế thế che giấu thông lượng bị mất phát sinh do quá trình giữ các luồng quá nhanh hoặc quá lâu vì rằng các lệnh từ các luồng khác vẫn có thể chạy trong khi một luồng bị giữ lạị Nhược điểm chính của phương pháp này là nó làm chậm quá trình chạy các luồng riêng rẽ vì rằng mỗi luồng sắp chạy mà không bị giữ lại sẽ phải bị làm trễ bởi các lệnh từ các luồng khác. Một cách tiếp cận khác là xử lý đa luồng thô. Đây là giải pháp được phát minh như là một giải pháp thay thếcho phương pháp đa luồng mịn. Phương pháp đa luồng thô tiến hành chuyển các luồng chỉ khi luồng này bị giữ lại đủ lâu, chẳng hạn như là bị giữ lại ở cache L2. Việc này làm giảm thời gian trễ khi thực hiện các luồng độc lập vì rằng một luồng chỉ bị làm trễ khi mà nó bị giữ lại đủ lâụ Đa luồng thô có một nhược điểm chính là khảnăng giảm thông lượng bị mất của nó luôn bị giới hạn, nhất là đối với các luồng có thời gian giữ lại ngắn.