Tại sao Intel lại giấu lõi RISC bên trong trong bộ vi xử lý của họ?


89

Bắt đầu với Pentium Pro (vi kiến ​​trúc P6), Intel đã thiết kế lại bộ vi xử lý và sử dụng lõi RISC bên trong theo hướng dẫn CISC cũ. Vì Pentium Pro nên tất cả các lệnh CISC được chia thành các phần nhỏ hơn (uops) và sau đó được thực thi bởi lõi RISC.

Lúc đầu, tôi thấy rõ ràng rằng Intel đã quyết định ẩn kiến ​​trúc nội bộ mới và buộc các lập trình viên phải sử dụng "CISC shell". Nhờ quyết định này mà Intel có thể thiết kế lại hoàn toàn kiến ​​trúc bộ vi xử lý mà không phá vỡ khả năng tương thích, điều đó là hợp lý.

Tuy nhiên tôi không hiểu một điều, tại sao Intel vẫn ẩn một bộ hướng dẫn RISC nội bộ trong nhiều năm như vậy? Tại sao họ không cho phép các lập trình viên sử dụng các hướng dẫn RISC giống như sử dụng các hướng dẫn CISC x86 cũ?

Nếu Intel giữ khả năng tương thích ngược quá lâu (chúng ta vẫn có chế độ 8086 ảo bên cạnh chế độ 64 bit), Tại sao họ không cho phép chúng ta biên dịch các chương trình để họ bỏ qua các lệnh CISC và sử dụng trực tiếp lõi RISC? Điều này sẽ mở ra một cách tự nhiên để từ từ từ bỏ tập lệnh x86, hiện không được dùng nữa (đây là lý do chính tại sao Intel quyết định sử dụng lõi RISC bên trong, phải không?).

Nhìn vào dòng Intel 'Core i' mới, tôi thấy rằng chúng chỉ mở rộng bộ lệnh CISC thêm AVX, SSE4 và các bộ khác.


1
lưu ý rằng có một số CPU x86 nhất định trong đó tập lệnh RISC nội bộ bị lộ
phuclv

Câu trả lời:


90

Không, tập lệnh x86 chắc chắn không bị phản đối. Nó là phổ biến hơn bao giờ hết. Lý do Intel sử dụng một bộ vi lệnh giống RISC trong nội bộ là vì chúng có thể được xử lý hiệu quả hơn.

Vì vậy, một CPU x86 hoạt động bằng cách có một bộ giải mã khá nặng trong giao diện người dùng, chấp nhận các lệnh x86 và chuyển đổi chúng sang một định dạng nội bộ được tối ưu hóa, mà phần phụ trợ có thể xử lý.

Đối với việc hiển thị định dạng này cho các chương trình "bên ngoài", có hai điểm:

  • nó không phải là một định dạng ổn định. Intel có thể thay đổi nó giữa các kiểu CPU để phù hợp nhất với kiến ​​trúc cụ thể. Điều này cho phép họ tối đa hóa hiệu quả và lợi thế này sẽ mất đi nếu họ phải sử dụng định dạng hướng dẫn cố định, ổn định để sử dụng nội bộ cũng như sử dụng bên ngoài.
  • không có gì để đạt được bằng cách làm điều đó. Với CPU khổng lồ và phức tạp ngày nay, bộ giải mã là một phần tương đối nhỏ của CPU. Việc phải giải mã các lệnh x86 khiến điều đó trở nên phức tạp hơn, nhưng phần còn lại của CPU không bị ảnh hưởng, vì vậy nhìn chung, chỉ đạt được rất ít, đặc biệt là vì giao diện người dùng x86 sẽ vẫn phải ở đó, để thực thi mã "kế thừa" . Vì vậy, bạn thậm chí sẽ không lưu các bóng bán dẫn hiện được sử dụng trên giao diện người dùng x86.

Đây không phải là một sự sắp xếp hoàn hảo, nhưng chi phí khá nhỏ và đó là một lựa chọn tốt hơn nhiều so với việc thiết kế CPU để hỗ trợ hai tập lệnh hoàn toàn khác nhau. (Trong trường hợp đó, họ có thể sẽ phát minh ra bộ vi hoạt động thứ ba để sử dụng nội bộ, chỉ vì chúng có thể được tinh chỉnh tùy ý để phù hợp nhất với kiến ​​trúc bên trong của CPU)


1
Điểm tốt. RISC là một kiến ​​trúc cốt lõi tốt, trong đó TỐT có nghĩa là chạy nhanh và có thể triển khai chính xác, và x86 ISA có lịch sử kiến ​​trúc CISC, bây giờ chỉ là, một bố cục tập lệnh có lịch sử khổng lồ và vô số phần mềm nhị phân có sẵn cho nó , cũng như hiệu quả để lưu trữ và xử lý. Nó không phải là một trình bao CISC, mà là ISA tiêu chuẩn defacto của ngành.
Warren P

2
@Warren: về phần cuối cùng, tôi thực sự không nghĩ vậy. Một tập lệnh CISC được thiết kế tốt sẽ hiệu quả hơn về mặt lưu trữ, vâng, nhưng từ một vài thử nghiệm mà tôi đã thấy, hướng dẫn x86 "trung bình" có chiều rộng như 4,3 byte, nhiều hơn mức thông thường. một kiến ​​trúc RISC. x86 mất rất nhiều hiệu quả lưu trữ vì nó được thiết kế và mở rộng quá lộn xộn trong những năm qua. Nhưng như bạn nói, sức mạnh chính của nó là lịch sử và lượng mã nhị phân khổng lồ hiện có.
jalf

1
Tôi không nói đó là "CISC được thiết kế tốt", chỉ là "lịch sử khổng lồ". Các bộ phận TỐT là các bộ phận thiết kế chip RISC.
Warren P

2
@jalf - Từ việc kiểm tra các tệp nhị phân thực tế, kích thước lệnh trong x86 trung bình khoảng 3 byte mỗi tệp. Tất nhiên, có nhiều hướng dẫn dài hơn, nhưng những hướng dẫn nhỏ hơn có xu hướng chiếm ưu thế trong sử dụng thực tế.
srking

1
Độ dài lệnh trung bình không phải là thước đo tốt về mật độ mã: loại lệnh x86 phổ biến nhất trong mã điển hình là tải và lưu trữ (chỉ di chuyển dữ liệu đến nơi nó có thể được xử lý và quay lại bộ nhớ, bộ xử lý RISC và khoảng ½ CISC có nhiều thanh ghi do đó, không cần phải làm nhiều này cũng bao nhiêu lon một hướng dẫn làm (hướng dẫn cánh tay có thể làm khoảng 3 thứ)..
ctrl-alt-delor

20

Câu trả lời thực sự là đơn giản.

Yếu tố chính đằng sau việc triển khai các bộ xử lý RISC là giảm độ phức tạp và tăng tốc độ. Nhược điểm của RISC là mật độ lệnh giảm, điều đó có nghĩa là cùng một mã được thể hiện dưới dạng RISC giống như định dạng cần nhiều lệnh hơn mã CISC tương đương.

Tác dụng phụ này không có ý nghĩa nhiều nếu CPU của bạn chạy ở cùng tốc độ với bộ nhớ, hoặc ít nhất là nếu cả hai đều chạy ở tốc độ hợp lý tương tự.

Hiện tại tốc độ bộ nhớ so với tốc độ CPU cho thấy sự khác biệt lớn về xung nhịp. CPU hiện tại đôi khi nhanh hơn bộ nhớ chính năm lần hoặc hơn.

Trạng thái công nghệ này tạo điều kiện cho mã dày đặc hơn, một thứ mà CISC cung cấp.

Bạn có thể tranh luận rằng bộ nhớ đệm có thể tăng tốc CPU RISC. Nhưng điều tương tự cũng có thể nói về cpus CISC.

Bạn nhận được sự cải thiện tốc độ lớn hơn bằng cách sử dụng CISC và bộ nhớ đệm hơn RISC và bộ nhớ đệm, bởi vì bộ nhớ đệm có cùng kích thước ảnh hưởng nhiều hơn đến mã mật độ cao mà CISC cung cấp.

Một tác dụng phụ khác là RISC khó triển khai trình biên dịch hơn. Nó dễ dàng hơn để tối ưu hóa trình biên dịch cho CISC cpus. Vân vân.

Intel biết họ đang làm gì.

Điều này đúng đến nỗi ARM có một chế độ mật độ mã cao hơn được gọi là Thumb.


1
Ngoài ra, một lõi RISC bên trong làm giảm số lượng bóng bán dẫn trên CPU CISC. Thay vì đi dây cứng cho mọi lệnh CISC, bạn có thể sử dụng vi mã để thực thi chúng. Điều này dẫn đến việc sử dụng lại các lệnh vi mã RISC cho các lệnh CISC khác nhau do đó sử dụng ít diện tích khuôn hơn.
Sil

16

Nếu Intel giữ khả năng tương thích ngược quá lâu (chúng ta vẫn có chế độ 8086 ảo bên cạnh chế độ 64 bit), Tại sao họ không cho phép chúng ta biên dịch các chương trình để họ bỏ qua các lệnh CISC và sử dụng trực tiếp lõi RISC? Điều này sẽ mở ra một cách tự nhiên để từ từ từ bỏ tập lệnh x86, hiện không được dùng nữa (đây là lý do chính tại sao Intel quyết định sử dụng lõi RISC bên trong, phải không?).

Bạn cần nhìn nhận ở góc độ kinh doanh của việc này. Intel đã thực sự cố gắng loại bỏ x86, nhưng đó là con ngỗng đẻ trứng vàng cho công ty. XScale và Itanium thậm chí chưa bao giờ đạt đến mức độ thành công mà mảng kinh doanh x86 cốt lõi của họ có được.

Về cơ bản, những gì bạn đang yêu cầu là để Intel cắt cổ tay của mình để đổi lấy những chiếc lông tơ ấm áp từ các nhà phát triển. Phá hoại x86 không phải là lợi ích của họ. Bất cứ điều gì khiến nhiều nhà phát triển không phải chọn nhắm mục tiêu x86 sẽ làm suy yếu x86. Điều đó, đến lượt nó, làm suy yếu chúng.


6
Đúng vậy, khi Intel cố gắng làm điều này (Itanium), thị trường chỉ đáp lại bằng một cái nhún vai.
Warren P

Cần lưu ý rằng có nhiều yếu tố khác nhau trong khi Itanium thất bại, và không chỉ vì nó là một kiến ​​trúc mới. Ví dụ: lập lịch trình giảm tải CPU đến một trình biên dịch mà không bao giờ thực sự đạt được mục tiêu của nó. Nếu Itanium nhanh hơn 10 lần hoặc 100 lần so với CPU x86, nó sẽ bán chạy như tôm tươi. Nhưng nó không nhanh hơn.
Katastic Voyage,

5

Đáp án đơn giản. Intel không phát triển CPU cho các nhà phát triển ! Họ đang phát triển chúng cho những người đưa ra quyết định mua hàng , BTW, là điều mà mọi công ty trên thế giới đều làm!

Từ lâu, Intel đã cam kết rằng (tất nhiên là có lý do), CPU của họ sẽ vẫn tương thích ngược. Mọi người muốn biết rằng, khi họ mua một máy tính Intel mới, tất cả các phần mềm hiện tại của họ sẽ chạy giống hệt như trên máy tính cũ của họ. (Mặc dù, hy vọng là nhanh hơn!)

Hơn nữa, Intel biết chính xác cam kết đó quan trọng như thế nào, bởi vì họ đã từng cố gắng đi theo một con đường khác. Chính xác thì bạn biết bao nhiêu người với CPU Itanium?!?

Bạn có thể không thích nó, nhưng một quyết định, ở lại với x86, là điều đã khiến Intel trở thành một trong những tên tuổi doanh nghiệp dễ nhận biết nhất trên thế giới!


2
Tôi không đồng ý với cách nói bóng gió rằng bộ xử lý Intel không thân thiện với nhà phát triển. Đã lập trình PowerPC và x86 trong nhiều năm, tôi tin rằng CISC thân thiện với lập trình viên hơn nhiều. (Tôi làm việc cho Intel bây giờ, nhưng tôi quyết tâm của tôi về vấn đề này trước khi tôi được tuyển dụng.)
Jeff

1
@Jeff Đó hoàn toàn không phải là ý định của tôi! Câu hỏi đặt ra là tại sao Intel vẫn chưa mở tập lệnh RISC để các nhà phát triển có thể sử dụng nó. Tôi không nói về việc x86 không thân thiện với nhà phát triển. Những gì tôi nói là quyết định như thế này đã được chưa quyết định với các nhà phát triển trong tâm trí , nhưng, đúng hơn, là nghiêm chỉnh quyết định kinh doanh.
geo

5

Câu trả lời của @ jalf bao gồm hầu hết các lý do, nhưng có một chi tiết thú vị mà nó không đề cập đến: Lõi giống RISC bên trong không được thiết kế để chạy một tập lệnh bất kỳ thứ gì như ARM / PPC / MIPS. Thuế x86 không chỉ được trả trong các bộ giải mã ngốn điện, mà ở một mức độ nào đó trong toàn bộ lõi. tức là nó không chỉ là mã hóa lệnh x86; đó là mọi hướng dẫn với ngữ nghĩa kỳ lạ.

Hãy giả sử rằng Intel đã tạo ra một chế độ hoạt động trong đó luồng lệnh là một thứ gì đó khác với x86, với các lệnh ánh xạ trực tiếp hơn tới các uops. Cũng giả sử rằng mỗi kiểu CPU có ISA riêng cho chế độ này, vì vậy chúng vẫn có thể tự do thay đổi bên trong khi chúng muốn và để lộ chúng với một lượng bóng bán dẫn tối thiểu để giải mã lệnh của định dạng thay thế này.

Có lẽ bạn vẫn chỉ có cùng một số lượng thanh ghi, được ánh xạ tới trạng thái kiến ​​trúc x86, vì vậy hệ điều hành x86 có thể lưu / khôi phục nó trên các công tắc ngữ cảnh mà không cần sử dụng tập lệnh dành riêng cho CPU. Nhưng nếu chúng ta loại bỏ hạn chế thực tế đó, vâng chúng ta có thể có thêm một vài thanh ghi vì chúng ta có thể sử dụng các thanh ghi tạm thời ẩn thường được dành cho vi mã 1 .


Nếu chúng ta chỉ có các bộ giải mã thay thế mà không có thay đổi đối với các giai đoạn đường ống sau này (đơn vị thực thi), ISA này sẽ vẫn có nhiều điểm lệch tâm x86. Nó sẽ không phải là một kiến ​​trúc RISC rất đẹp. Không có hướng dẫn đơn lẻ nào sẽ rất phức tạp, nhưng một số sự điên rồ khác của x86 vẫn sẽ ở đó.

Ví dụ: dịch chuyển trái / phải để lại cờ Tràn không xác định, trừ khi số dịch chuyển là một, trong trường hợp đó OF = phát hiện tràn có dấu thông thường. Sự điên rồ tương tự cho các vòng quay. Tuy nhiên, các hướng dẫn RISC tiếp xúc có thể cung cấp các thay đổi không gắn cờ, v.v. (cho phép chỉ sử dụng một hoặc hai trong số nhiều uops thường đi vào một số lệnh x86 phức tạp). Vì vậy, đây không thực sự được coi là lập luận phản bác chính.

Nếu bạn định tạo một bộ giải mã hoàn toàn mới cho RISC ISA, bạn có thể yêu cầu nó chọn và chọn các phần của lệnh x86 sẽ được hiển thị dưới dạng hướng dẫn RISC. Điều này làm giảm bớt phần nào sự chuyên môn hóa x86 của lõi.


Mã hóa lệnh có thể sẽ không có kích thước cố định, vì các uops đơn lẻ có thể chứa rất nhiều dữ liệu. Nhiều dữ liệu hơn là có ý nghĩa nếu tất cả các phần trong có cùng kích thước. Một uop hợp nhất vi mô duy nhất có thể thêm một toán hạng bộ nhớ và ngay lập tức 32 bit sử dụng chế độ định địa chỉ với 2 thanh ghi và sự dịch chuyển 32 bit. (Trong SnB trở lên, chỉ các chế độ định địa chỉ thanh ghi đơn mới có thể kết hợp vi mô với các hoạt động ALU).

uops rất lớn và không giống với các lệnh ARM có chiều rộng cố định. Tập lệnh 32bit có độ rộng cố định chỉ có thể tải 16bit ngay lập tức tại một thời điểm, do đó, việc tải một địa chỉ 32bit yêu cầu một cặp nửa thấp / tải cao-tức thì tải ngay lập tức. x86 không cần phải làm điều đó, điều này giúp nó không quá tệ với chỉ 15 thanh ghi GP hạn chế khả năng giữ các hằng số xung quanh trong các thanh ghi. (15 là một trợ giúp lớn hơn 7 thanh ghi, nhưng tăng gấp đôi một lần nữa lên 31 sẽ giúp ít hơn nhiều, tôi nghĩ rằng một số mô phỏng đã tìm thấy. RSP thường không phải là mục đích chung, vì vậy nó giống như 15 thanh ghi GP và một ngăn xếp.)


Tóm tắt TL; DR:

Dù sao, câu trả lời này tóm gọn lại thành "tập lệnh x86 có lẽ là cách tốt nhất để lập trình một CPU có thể chạy các lệnh x86 một cách nhanh chóng", nhưng hy vọng sẽ làm sáng tỏ lý do.


Định dạng uop nội bộ trong front-end so với back-end

Xem thêm Chế độ kết hợp vi mô và chế độ địa chỉ để biết một trường hợp khác biệt về những gì định dạng uop front-end so với back-end có thể thể hiện trên CPU Intel.

Chú thích chân trang 1 : Có một số thanh ghi "ẩn" để sử dụng làm mã tạm thời bằng vi mã. Các thanh ghi này được đổi tên giống như các thanh ghi kiến ​​trúc x86, vì vậy các lệnh multi-uop có thể thực thi không theo thứ tự.

ví dụ: xchg eax, ecxtrên CPU Intel giải mã dưới dạng 3 uops ( tại sao? ), và dự đoán tốt nhất của chúng tôi là đây là những uops giống MOV tmp = eax; ecx=eax ; eax=tmp;. Theo thứ tự đó, bởi vì tôi đo độ trễ của hướng dst-> src ở ~ 1 chu kỳ, so với 2 đối với cách khác. Và những bước di chuyển này không giống như những movhướng dẫn thông thường ; chúng dường như không phải là ứng cử viên để loại bỏ mov độ trễ bằng 0.

Xem thêm http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/ để biết về việc cố gắng đo kích thước PRF bằng thực nghiệm và phải tính đến các thanh ghi vật lý được sử dụng để giữ trạng thái kiến ​​trúc, bao gồm cả thanh ghi ẩn.

Trong giao diện người dùng sau bộ giải mã, nhưng trước giai đoạn vấn đề / đổi tên đổi tên các đăng ký vào tệp đăng ký vật lý, định dạng uop nội bộ sử dụng số đăng ký tương tự như số reg x86, nhưng có chỗ để giải quyết các thanh ghi ẩn này.

Định dạng uop hơi khác bên trong lõi không theo thứ tự (ROB và RS), hay còn gọi là back-end (sau giai đoạn vấn đề / đổi tên). Mỗi tệp thanh ghi vật lý int / FP có 168 mục nhập trong Haswell , vì vậy mỗi trường đăng ký trong một uop cần phải đủ rộng để giải quyết nhiều trường đó.

Vì bộ đổi tên có trong HW, nên chúng ta có lẽ tốt hơn nên sử dụng nó, thay vì cung cấp các hướng dẫn được lập lịch tĩnh trực tiếp cho back-end. Vì vậy, chúng tôi sẽ làm việc với một tập hợp các thanh ghi lớn như các thanh ghi kiến ​​trúc x86 + thời gian tạm thời vi mã, không nhiều hơn thế.

Back-end được thiết kế để hoạt động với bộ đổi tên front-end để tránh các nguy cơ WAW / WAR, vì vậy chúng tôi không thể sử dụng nó như một CPU đặt hàng ngay cả khi chúng tôi muốn. Nó không có khóa liên động để phát hiện những phụ thuộc đó; được xử lý bởi sự cố / đổi tên.

Có thể rất gọn gàng nếu chúng ta có thể đưa các uops vào back-end mà không bị tắc nghẽn ở giai đoạn vấn đề / đổi tên (điểm hẹp nhất trong các đường ống Intel hiện đại, ví dụ: 4-wide trên Skylake so với 4 ALU + 2 tải + 1 cổng lưu trữ trong phía sau). Nhưng nếu bạn đã làm điều đó, tôi không nghĩ rằng bạn có thể lên lịch tĩnh mã để tránh việc sử dụng lại đăng ký và bước vào kết quả vẫn cần thiết nếu lỗi bộ nhớ cache làm ngừng tải trong một thời gian dài.

Vì vậy, chúng tôi cần phải cung cấp rất nhiều uops cho giai đoạn vấn đề / đổi tên, có thể chỉ bỏ qua giải mã, không phải bộ nhớ cache uop hoặc IDQ. Sau đó, chúng tôi nhận được trình điều hành OoO bình thường với phát hiện nguy cơ lành mạnh. Bảng phân bổ thanh ghi chỉ được thiết kế để đổi tên 16 + một số thanh ghi số nguyên thành số nguyên 168 mục nhập PRF. Chúng tôi không thể mong đợi HW đổi tên một tập hợp các thanh ghi logic lớn hơn thành cùng một số thanh ghi vật lý; điều đó sẽ mất RAT lớn hơn.


-3

Tại sao họ không cho phép chúng tôi biên dịch các chương trình để họ bỏ qua các hướng dẫn của CISC và sử dụng lõi RISC trực tiếp?

Ngoài những câu trả lời trước, một nguyên nhân khác là sự phân khúc thị trường. Một số hướng dẫn được cho là được triển khai bằng mã vi mô chứ không phải trong phần cứng, do đó, việc cho phép bất kỳ ai thực hiện các vi hoạt động tùy ý có thể làm suy yếu việc bán các cp mới bằng các lệnh CISC "mới" hiệu quả hơn.


1
Tôi không nghĩ điều này có ý nghĩa. RISC có thể sử dụng vi mã, đặc biệt nếu chúng ta đang nói về việc chỉ thêm bộ giải mã RISC vào giao diện người dùng x86.
Peter Cordes

2
Điều đó vẫn sai. Hướng dẫn AES mới (và hướng dẫn SHA sắp tới) và những thứ khác như PCLMULQDQ có phần cứng chuyên dụng. Trên Haswell, AESENC giải mã thành một uop ( agner.org/optimize ), vì vậy nó chắc chắn không được mã hóa vi mô. (Các bộ giải mã chỉ cần kích hoạt sequencer ROM vi để được hướng dẫn rằng decode đến hơn 4 UOPs .)
Peter Cordes

1
Bạn nói đúng rằng một số hướng dẫn mới chỉ sử dụng chức năng hiện có theo cách không có sẵn với hướng dẫn x86. Một ví dụ điển hình sẽ là BMI2 SHLX , cho phép bạn thực hiện thay đổi số lượng biến đổi mà không cần đặt số lượng vào CL và không phát sinh thêm các lỗi cần thiết để xử lý ngữ nghĩa cờ x86 tồi tệ (cờ không được sửa đổi nếu số lượng dịch chuyển bằng 0, vì vậy SHL r/m32, clcó . một sự phụ thuộc đầu vào FLAGS, và giải mã tới 3 UOPs trên Skylake Đó là chỉ có 1 UOP trên Core2 / Nehalem, tuy nhiên, theo thử nghiệm Agner sương mù của).
Peter Cordes

Cảm ơn bạn đã bình luận của bạn.
KOLANICH
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.