Làm thế nào có ngôn ngữ ảnh hưởng đến thiết kế CPU? [đóng cửa]


44

Chúng ta thường được thông báo rằng phần cứng không quan tâm chương trình được viết bằng ngôn ngữ nào vì nó chỉ nhìn thấy mã nhị phân được biên dịch, tuy nhiên đây không phải là toàn bộ sự thật. Ví dụ, hãy xem xét Z80 khiêm tốn; các phần mở rộng của nó cho tập lệnh 8080 bao gồm các hướng dẫn như CPIR rất hữu ích để quét các chuỗi kiểu C (chấm dứt NULL), ví dụ để thực hiện strlen(). Các nhà thiết kế phải xác định rằng việc chạy các chương trình C (trái ngược với Pascal, trong đó độ dài của chuỗi trong tiêu đề) là thứ mà thiết kế của họ có thể được sử dụng cho. Một ví dụ kinh điển khác là Máy Lisp .

Những ví dụ khác là gì? Ví dụ: hướng dẫn, số lượng và loại thanh ghi , chế độ địa chỉ, làm cho một bộ xử lý cụ thể ủng hộ các quy ước của một ngôn ngữ cụ thể? Tôi đặc biệt quan tâm đến các phiên bản của cùng một gia đình.


3
Đừng quên rằng Z-80 cũng có hướng dẫn LDIR, rất hữu ích khi sao chép chuỗi khi bạn biết độ dài (như trong Pascal, nơi độ dài được lưu trữ trong tiêu đề).
TMN

27
1. Z-80 được thiết kế vào năm 1975, khi Unix và C là một hệ điều hành và ngôn ngữ tối nghĩa trên một vài máy tính, 3 năm trước phiên bản đầu tiên của K & R. 2. Không có gì về Pascal bắt buộc độ dài chuỗi là "trong một tiêu đề." 3. Các chuỗi trong CP / M, hệ điều hành máy vi tính chính tại thời điểm đó, đã bị chấm dứt với ký tự '$', không phải '\ 0'. CPIR có thể tìm kiếm bất kỳ nhân vật. 4. CPIR được khớp với CPDR (tìm kiếm ngược), cũng như các hướng dẫn -IR và -DR khác. Kết luận: CPIR không liên quan gì đến ngôn ngữ lập trình C. Nó chỉ là một hướng dẫn tìm kiếm byte.
librik

4
Cái lớn nhất (và một trong những điều khó chịu nhất đối với các nhà thiết kế phần cứng) trong những điều mà C buộc phải là một địa chỉ byte. CPU sẽ đơn giản hơn và nhanh hơn nếu không có sự ghê tởm này.
SK-logic

1
@ SK-logic: Mặc dù tiêu chuẩn POSIX yêu cầu địa chỉ byte, nhưng tiêu chuẩn C thì không. Bất kỳ việc thực hiện nào sizeof(int)bằng 1 phải yêu cầu loại đó charđược ký (vì intphải có khả năng giữ tất cả các giá trị của loại char). Tôi đã viết mã cho một máy trong đó charintcả hai số nguyên có chữ ký 16 bit; những khó khăn lớn nhất là người ta không thể sử dụng các hiệp hội để chuyển đổi loại và việc lưu trữ hiệu quả số lượng lớn byte yêu cầu đóng gói và giải nén thủ công. Những vấn đề đó không đáng kể so với khả năng trong C đó sizeof (int) == sizeof (dài), vì ...
supercat

2
... Điều đó có nghĩa là không có loại tiêu chuẩn nào được đảm bảo giữ chênh lệch giữa hai unsigned intgiá trị. C99 đã cải thiện tình hình đó, nhưng trước C99, không có cách nào một bước an toàn được đảm bảo để so sánh giá trị âm với giá trị của loại unsigned int(người ta sẽ phải kiểm tra xem số đó có âm hay không trước khi so sánh).
supercat

Câu trả lời:


20

Các câu trả lời hiện có tập trung vào các thay đổi của ISA . Có những thay đổi phần cứng khác, quá. Chẳng hạn, C ++ thường sử dụng vtables cho các cuộc gọi ảo. Bắt đầu với Pentium M , Intel có thành phần "dự báo nhánh gián tiếp" giúp tăng tốc các cuộc gọi chức năng ảo.


6
Và kiến ​​trúc Berkeley RISC bao gồm khái niệm "tệp đăng ký", vì vậy thay vì thực hiện các chức năng "tràn" các thanh ghi lên ngăn xếp, một khối 8 thanh ghi được cung cấp cho mỗi chức năng. Điều này tăng tốc mã hướng đối tượng đáng kể, vì nó có xu hướng bao gồm nhiều lệnh gọi phương thức đến các phương thức ngắn.
TMN

1
Đây không phải là một ví dụ hợp lệ. Thiết kế "Bảng con trỏ hàm" cũng được sử dụng trong nhiều tình huống liên kết động, ví dụ, thông qua nhập và xuất DLL trên Windows, và cũng được sử dụng trong các chương trình C. Mặc dù tôi đoán bạn có thể lập luận rằng nó cho thấy bộ xử lý được tối ưu hóa cho một mục đích sử dụng cụ thể, nhưng nó không phải là ngôn ngữ cụ thể.
DeadMG

@DeadMG: Các trường hợp khác được hưởng lợi, đó là sự thật. Nhưng cho đến khi C ++ trở nên phổ biến, các thiết kế CPU không bị ảnh hưởng . Và đó là câu hỏi được đặt ra. Tương tự, TMN có một điểm về các tệp đăng ký. Hội không có một khái niệm rõ ràng về chức năng. Các chức năng, như chúng ta thường hiểu chúng ngày nay, bắt nguồn từ Algol 60, và do đó chúng ta có thể nói rằng Algol 60 ảnh hưởng đến thiết kế tệp đăng ký CPU.
MSalters

14

Tập lệnh Intel 8086 bao gồm một biến thể "ret", thêm một giá trị vào con trỏ ngăn xếp sau khi bật địa chỉ trả về. Điều này hữu ích cho nhiều triển khai Pascal trong đó người gọi hàm sẽ đẩy các đối số lên ngăn xếp trước khi thực hiện cuộc gọi hàm và tắt chúng sau đó. Nếu một thường trình chấp nhận các tham số có giá trị bốn byte, thì nó có thể kết thúc bằng "RET 0004" để dọn sạch ngăn xếp. Không có hướng dẫn như vậy, một quy ước gọi như vậy có thể sẽ yêu cầu mã bật địa chỉ trả về vào một thanh ghi, cập nhật con trỏ ngăn xếp và sau đó nhảy đến thanh ghi đó.

Điều thú vị là hầu hết các mã (bao gồm các thói quen của hệ điều hành) trên Macintosh ban đầu đã sử dụng quy ước gọi Pascal mặc dù không có hướng dẫn thuận tiện trong 68000. Sử dụng quy ước gọi này đã lưu 2-4 byte mã tại một trang gọi thông thường, nhưng cần thêm 4 - 6 byte mã tại vị trí trả về của mọi hàm lấy tham số.


Ngoài ra còn có ENTERđối tác với điều này RET n...
herby

1
@herby: Tôi không nghĩ ENTERđã tồn tại trong bản gốc 8086; nó đi kèm với bộ xử lý sau này. Mặc dù vậy, nó mang đến một điểm thú vị: các chế độ địa chỉ dựa trên BP được thiết kế rõ ràng xung quanh việc sử dụng các tham số xếp chồng và các địa phương được truy cập thông qua con trỏ khung. Tôi thấy quy ước này thú vị theo một số cách, đặc biệt khi xem xét rằng (1) mã ngôn ngữ lắp ráp thuần túy có khả năng sử dụng các giá trị trong các thanh ghi hơn so với ngăn xếp, nhưng (2) các ưu điểm của [BP + nn] giải quyết trên [SP + nn] địa chỉ có ý nghĩa hơn đối với các chương trình ngôn ngữ lắp ráp truy cập mọi thứ trên ngăn xếp so với ...
supercat

... cho mã lắp ráp viết tay. Một trình biên dịch thường sẽ biết, đối với mỗi lệnh được tạo, cách so sánh SP và BP; ví dụ, nếu SP là BP-8, thì trình biên dịch thực sự không dễ dàng xử lý [BP + 12] hơn [SP + 20]. Nếu trên một trình biên dịch lại, trình biên dịch phải thêm một PUSH / POP khác xung quanh một khối mã, nó có thể điều chỉnh các độ lệch dựa trên SP một cách thích hợp. Mặt khác, trong phần lắp ráp viết tay, việc thêm PUSH / POP nhiều khả năng sẽ yêu cầu điều chỉnh mã giữa chúng. Vì vậy, con trỏ khung chủ yếu là một lợi ích cho mã cấp cao / mã asm kết hợp.
supercat

Có thể khả năng sử dụng lại mã mà không cần biên dịch lại cũng là một số điểm khả dụng cận biên để đánh địa chỉ BP. Và Chúa biết nếu BP hướng dẫn việc giải quyết không phải là nhanh hơn trong mạch hơn SP giải quyết những người thân, kể từ khi BP quyết là loại tiêu chuẩn ...
Herby

3
@herby: Trên thực tế, tôi nghi ngờ một phần lớn các lý do trình biên dịch thường sử dụng con trỏ khung có liên quan nhiều đến việc gỡ lỗi. Để gỡ lỗi một chương trình không sử dụng quy ước như vậy sẽ yêu cầu trình biên dịch tạo ra - và trình gỡ lỗi sử dụng - một tệp liệt kê bù SP-BP cho mỗi lệnh. Siêu dữ liệu chi tiết như vậy là phổ biến ngày nay (và là một phần thiết yếu của những gì làm cho ngôn ngữ thu gom rác trở nên thiết thực) nhưng lượng RAM mà nó yêu cầu sẽ không được chấp nhận 30 năm trước.
supercat

10

Một ví dụ là MIPS, có cả hai addadduđể bẫy và bỏ qua tràn tương ứng. (Ngoài ra subsubu.) Nó cần loại hướng dẫn đầu tiên cho các ngôn ngữ như Ada (tôi nghĩ - tôi chưa bao giờ thực sự sử dụng Ada) mà xử lý tràn một cách rõ ràng và loại thứ hai cho các ngôn ngữ như C mà bỏ qua tràn.

Nếu tôi nhớ chính xác, CPU thực tế có một số mạch bổ sung trong ALU để theo dõi tràn. Nếu ngôn ngữ duy nhất mọi người quan tâm là C, thì nó sẽ không cần thứ này.


Không chắc chắn nếu có liên quan, nhưng những hướng dẫn đó có thể cũng hữu ích trong các tình huống khác, như phân bổ bộ nhớ an toàn, tức là nếu bạn đang phân bổ nmemb*size+offsetbyte và cần đảm bảo rằng bạn không bị tràn.
NikiC

@NikC: Tôi đã nghĩ rằng adduvà các subuhướng dẫn (những thứ không kiểm tra tràn) là những thứ được thêm vào để làm cho C hạnh phúc. Tất nhiên, tôi không thực sự biết - chúng tôi chỉ nói một cách mơ hồ trong bài giảng và tôi chắc chắn không có chuyên gia về kiến ​​trúc: P.
Tikhon Jelvis

Ồ vâng, tôi đã suy nghĩ theo cách khác, xin lỗi: /
NikiC

8

Sê-ri Burroughs 5000 được thiết kế để hỗ trợ ALGOL hiệu quả và iAPX-432 của Intel được thiết kế để thực hiện Ada một cách hiệu quả. Inmos Transputer có ngôn ngữ riêng, Occam. Tôi nghĩ rằng bộ xử lý Parallax "Propeller" được thiết kế để được lập trình bằng biến thể BASIC của riêng nó.

Đó không phải là ngôn ngữ, nhưng tập lệnh VAX-11 có một lệnh duy nhất để tải bối cảnh quy trình, được thiết kế sau khi có yêu cầu từ nhóm thiết kế VMS. Tôi không nhớ các chi tiết, nhưng ISTR đã mất rất nhiều hướng dẫn để thực hiện đến mức nó đặt giới hạn trên nghiêm trọng cho số lượng quy trình họ có thể lên lịch.


Điều gì về những thiết kế làm cho chúng đặc biệt phù hợp? Ví dụ, tính năng nào của iAPX mà Ada đặc biệt được hưởng lợi từ?
Gaius

ISTR rằng mục tiêu Ada của iAPX-432 đã cố gắng cứu một thiết kế thất bại bằng cách gắn nó vào một thứ gì đó với những kỳ vọng lớn hơn bất kỳ thứ gì khác.
AProgrammer

@AProgrammer: Tôi khá chắc chắn rằng iAPX-432 được thiết kế từ khi bắt đầu sử dụng Ada. Tôi thậm chí còn nhớ lại một số tin đồn rằng Intel sẽ không xuất bản bộ hướng dẫn, để ngăn cản lập trình ngôn ngữ lắp ráp và buộc mọi người sử dụng Ada cho mọi thứ.
TMN

1
@TMN, dự án 432 của Intel bắt đầu vào năm 1975 và được giới thiệu vào năm 1981 (Wikipedia). Ironman (yêu cầu cuối cùng cho Ada), được xuất bản vào tháng 1 năm 1977 và màu xanh lá cây đã được chọn vào tháng 5 năm 1979, đã được sửa đổi và kết quả cuối cùng được công bố là một tiêu chuẩn quân sự vào tháng 7 năm 1980. Có một vấn đề về thời gian trong đó nêu rõ iAPX-432 được thiết kế từ bắt đầu sử dụng Ada. (Đây là bộ xử lý "thu hẹp khoảng cách ngữ nghĩa" muộn và điển hình với những nhược điểm thường thấy tại thời điểm các lựa chọn thay thế bắt đầu được tìm kiếm; tiếp thị nó vì bộ xử lý Ada là dự kiến ​​để cứu một thiết kế thất bại - ISTR mà không ai ngoài Intel sử dụng )
Lập trình viên

1
@AProgrammer: Hmmm, có vẻ như bạn đúng. Tôi đã chạy qua bài báo này từ kiến ​​trúc sư trưởng của 432 và trong bản tóm tắt, anh ta nói rằng "Sự kết hợp chặt chẽ giữa kiến ​​trúc và ngôn ngữ này đã không xảy ra vì 432 được thiết kế để thực hiện Ada Hồi không phải vậy." Tôi sẽ phải khai thác cuốn sách 432 cũ của mình và xem nó nói gì.
TMN

8

Một điều dường như không ai đề cập cho đến nay là những tiến bộ trong tối ưu hóa trình biên dịch (trong đó ngôn ngữ cơ bản không liên quan nhiều) đã chuyển sự thay đổi từ các bộ hướng dẫn CISC (phần lớn được thiết kế để mã hóa bởi con người) sang các bộ hướng dẫn RISC (phần lớn được thiết kế để được mã hóa bởi trình biên dịch.)


5

Gia đình Motorola 68000 đã giới thiệu một số địa chỉ tự động tăng tốc giúp sao chép dữ liệu qua cpu rất hiệu quả và nhỏ gọn.

[Ví dụ cập nhật]

đây là một số mã c ++ ảnh hưởng đến trình biên dịch 68000

while(someCondition)
    destination[destinationOffset++] = source[sourceOffset++]

được thực hiện trong trình biên dịch mã thông thường (mã giả, tôi quên các lệnh trình biên dịch 68000)

adressRegister1 = source
adressRegister2 = destination
while(someCondition) {
    move akku,(adressRegister1)
    move (adressRegister2), akku
    increment(adressRegister1, 1)
    increment(adressRegister2, 1)
}

với địa chỉ mới, nó trở thành một thứ gì đó tương tự

adressRegister1 = source
adressRegister2 = destination
while(someCondition) {
    move akku,(adressRegister1++)
    move (adressRegister2++), akku
}

chỉ có hai hướng dẫn trên mỗi vòng lặp thay vì 4.


1
Làm thế nào điều này bị ảnh hưởng bởi các quy ước của một ngôn ngữ cụ thể?
Gaius

xem ví dụ cập nhật
k3b

À, nhắc tôi về tối ưu hóa vòng lặp DBxx trong 68010.
Gaius

7
Trên thực tế, tôi nghĩ rằng bạn có điều này ngược. Địa chỉ tự động [in | de] crement là một phần của tập lệnh PDP-11, có khả năng ảnh hưởng đến thiết kế của C.
TMN

5

Máy tính lớn dòng Z của IBM, là hậu duệ của IBM 360 từ những năm 1960.

Có một số hướng dẫn được đưa vào đó để đặc biệt tăng tốc các chương trình COBOL và Fortran. Ví dụ kinh điển là BXLE- "Chi nhánh trên Chỉ số Thấp hoặc Bằng", hầu hết là một forvòng lặp Fortran hoặc một COBOL được PERFORM VARYING x from 1 by 1 until x > ngói gọn trong một lệnh đơn.

Ngoài ra còn có cả một nhóm các hướng dẫn thập phân được đóng gói để hỗ trợ số học thập phân điểm cố định phổ biến trong các chương trình COBOL.


Tôi nghĩ bạn có nghĩa là con cháu .
Đồng hồ-Muse

@ X-Zero - Rất tiếc! Sáng sớm, không đủ caffiene trong hệ thống, v.v ...
James Anderson

1
Thú vị hơn là hướng dẫn lặp lại khối của TI 32050 DSP. Toán hạng của nó là địa chỉ của lệnh theo sau cái cuối cùng trong vòng lặp; tải một thanh ghi đếm vòng lặp và sau đó thực hiện lệnh lặp lại khối sẽ khiến các lệnh lên đến (nhưng không bao gồm) mục tiêu được lặp lại với số lần chỉ định. Rất gợi nhớ về một DOvòng lặp FORTRAN .
supercat

@supercat Mỗi DSP xứng đáng với tên gọi bao gồm ba tính năng: vòng lặp không chi phí, tích lũy nhân lệnh đơn lẻ và một chế độ địa chỉ đảo ngược bit nào đó. Hầu như mọi thuật toán DSP được Man biết đến đều sử dụng các vòng lặp. Hai thuật toán phổ biến nhất là bộ lọc FIR, là một vòng lặp xung quanh tích lũy nhân và FFT, trong đó địa chỉ đảo ngược bit là rất quan trọng. Nhiều DSP bao gồm một hoạt động bướm FFT radix-2 một hướng dẫn, hoặc nhân / thêm kép có thể được sử dụng để tạo ra một con bướm một hướng dẫn.
John R. Strohm

@ JohnR.Strohm: Mỗi DSP tôi đã thấy bao gồm tích lũy nhân lặp lại, nhưng không phải tất cả chúng đều bao gồm các vòng lặp không chi phí tổng quát hơn. Trên thực tế, tôi không chắc chắn tại sao các vòng lặp như vậy chỉ được coi là một tính năng "DSP", vì chúng cũng hữu ích trong rất nhiều mã "bộ xử lý thông thường".
supercat

3

Các CPU Intel đời đầu có các tính năng sau, nhiều trong số chúng hiện đã lỗi thời ở chế độ 64 bit:

  • Các hướng dẫn nn ENTER, LEAVE và RET [hướng dẫn ban đầu được nói rõ ràng những hướng dẫn được giới thiệu cho các ngôn ngữ có cấu trúc khối, ví dụ: Pascal, hỗ trợ các thủ tục lồng nhau]
  • hướng dẫn tăng tốc số học BCD (AAA, AAM, v.v.); cũng hỗ trợ BCD trong x87
  • Hướng dẫn JCXZ và LOOP để thực hiện các vòng lặp được tính
  • INTO, để tạo bẫy trên tràn số học (ví dụ: trong Ada)
  • XLAT cho tra cứu bảng
  • BOUND để kiểm tra giới hạn mảng

Cờ ký hiệu, được tìm thấy trong thanh ghi trạng thái của nhiều CPU, tồn tại để dễ dàng thực hiện số học đã ký VÀ không dấu.

Tập lệnh SSE 4.1 giới thiệu các hướng dẫn xử lý chuỗi, cả được tính và không kết thúc (PCMPESTR, v.v.)

Ngoài ra, tôi có thể tưởng tượng rằng một số tính năng ở cấp hệ thống được thiết kế để hỗ trợ an toàn cho mã được biên dịch (kiểm tra giới hạn phân đoạn, cổng gọi với sao chép tham số, v.v.)


3

Một số bộ xử lý ARM, chủ yếu là các bộ xử lý trong thiết bị di động, bao gồm (d) phần mở rộng Jazelle, là trình thông dịch JVM phần cứng; nó giải thích trực tiếp mã byte Java. JVM nhận biết Jazelle có thể sử dụng phần cứng để tăng tốc độ thực thi và loại bỏ phần lớn JIT, nhưng dự phòng VM vẫn được đảm bảo nếu mã byte có thể được giải thích trên chip.

Bộ xử lý với đơn vị như vậy bao gồm lệnh BXJ, đặt bộ xử lý ở chế độ "Jazelle" đặc biệt hoặc nếu kích hoạt thiết bị không thành công, nó chỉ được hiểu là hướng dẫn chi nhánh thông thường. Đơn vị sử dụng lại các thanh ghi ARM để giữ trạng thái JVM.

Sự kế thừa cho công nghệ Jazelle là ThumbEE


2

Theo tôi biết điều này là phổ biến hơn trong quá khứ.

một phiên câu hỏi trong đó James Gosling nói rằng có những người đang cố gắng tạo ra phần cứng có thể xử lý tốt hơn với mã byte JVM, nhưng sau đó những người này sẽ tìm ra cách để làm điều đó với intel x86 "chung" (có thể biên dịch mã byte theo một cách thông minh nào đó).

Ông nói rằng có lợi thế trong việc sử dụng chip phổ biến chung (chẳng hạn như intel) bởi vì nó có một tập đoàn lớn ném một khoản tiền lớn vào sản phẩm.

Video đáng để xem. Anh ấy nói về điều này vào phút 19 hoặc 20.


2

Tôi đã thực hiện một tìm kiếm trang nhanh và dường như không ai đề cập đến CPU được phát triển đặc biệt để thực thi Forth . Các ngôn ngữ lập trình Forth được ngăn xếp dựa, nhỏ gọn, và được sử dụng trong hệ thống điều khiển.


2

Các iAPX Intel CPU được thiết kế đặc biệt cho các ngôn ngữ OO. Mặc dù vậy, không hoàn toàn làm việc ra.

Các iAPX 432 ( intel nâng cao kiến trúc bộ xử lý ) đã thiết kế bộ vi xử lý 32-bit đầu tiên của Intel, được giới thiệu vào năm 1981 như là một bộ ba mạch tích hợp. Nó được dự định là thiết kế chính của Intel trong những năm 1980, thực hiện nhiều tính năng quản lý bộ nhớ và đa nhiệm tiên tiến. Do đó, thiết kế được gọi là Micromainframe ...

IAPX 432 được "thiết kế để được lập trình hoàn toàn bằng các ngôn ngữ cấp cao" , với Ada là chính và nó hỗ trợ lập trình hướng đối tượngthu gom rác trực tiếp trong phần cứng và vi mã . Hỗ trợ trực tiếp cho các cấu trúc dữ liệu khác nhau cũng nhằm mục đích cho phép các hệ điều hành hiện đại cho iAPX 432 được triển khai bằng cách sử dụng mã chương trình ít hơn nhiều so với các bộ xử lý thông thường. Các tính chất và tính năng này dẫn đến một thiết kế phần cứng và vi mã phức tạp hơn nhiều so với hầu hết các bộ xử lý của thời đại, đặc biệt là bộ vi xử lý.

Sử dụng công nghệ bán dẫn thời đó, các kỹ sư của Intel không thể dịch thiết kế thành triển khai đầu tiên rất hiệu quả. Cùng với việc thiếu tối ưu hóa trong trình biên dịch Ada sớm, điều này đã góp phần vào các hệ thống máy tính khá chậm nhưng đắt tiền, thực hiện các điểm chuẩn điển hình với tốc độ bằng khoảng 1/4 tốc độ của chip 80286 mới ở cùng tần số (đầu năm 1982).

Khoảng cách hiệu suất ban đầu với cấu hình khá thấp và dòng 8086 giá thấp này có lẽ là lý do chính khiến kế hoạch của Intel thay thế cái sau (sau này gọi là x86) bằng iAPX 432 không thành công. Mặc dù các kỹ sư đã tìm ra cách để cải thiện thiết kế thế hệ tiếp theo, kiến trúc Khả năng của iAPX 432 giờ đây đã bắt đầu được coi là một chi phí triển khai hơn là hỗ trợ đơn giản hóa.

Dự án iAPX 432 là một thất bại thương mại cho Intel ...


Đọc bài báo, có vẻ như nhiều khía cạnh của thiết kế có thể hữu ích trong các khung hướng đối tượng như là phổ biến ngày nay. Một kiến ​​trúc sử dụng kết hợp giữa id đối tượng 32 bit và offset 32 ​​bit trong nhiều trường hợp có thể cung cấp hiệu năng bộ nhớ đệm tốt hơn so với một trong đó id đối tượng là tất cả 64 bit (trong hầu hết các trường hợp, một ứng dụng sẽ sử dụng hàng tỷ đối tượng được phục vụ tốt hơn bằng cách thay vì có nhiều hơn, những cái lớn hơn, một cái sẽ lưu trữ hàng tỷ byte trong một đối tượng sẽ được phục vụ tốt hơn khi chia nó thành các đối tượng nhỏ hơn.
supercat

1

68000 có MOVEM phù hợp nhất để đẩy nhiều thanh ghi lên ngăn xếp trong một lệnh duy nhất, đó là điều mà nhiều ngôn ngữ mong đợi.

Nếu bạn đã thấy MOVEM (MOVE Nhiều) trước JSR (Jump SubRoutine) trong toàn bộ mã thì bạn thường biết rằng bạn đang xử lý mã tuân thủ C.

MOVEM cho phép tự động tăng thanh ghi đích cho phép mỗi lần sử dụng tiếp tục xếp chồng trên đích hoặc xóa khỏi ngăn xếp trong trường hợp tự động giảm.

http://68k.hax.com/MOVEM


1

Kiến trúc AVR của Atmel hoàn toàn được thiết kế từ đầu để phù hợp với lập trình trong C. Ví dụ, ghi chú ứng dụng này sẽ phát triển thêm.

IMO điều này có liên quan chặt chẽ với câu trả lời tuyệt vời của rockets4kids , với PIC16 đầu tiên được phát triển để lập trình trình biên dịch trực tiếp (tổng cộng 40 lệnh), với các gia đình sau này nhắm mục tiêu C.


1

Khi bộ đồng xử lý số 8087 được thiết kế, các ngôn ngữ khá phổ biến để thực hiện tất cả các phép toán dấu phẩy động bằng cách sử dụng loại có độ chính xác cao nhất và chỉ làm tròn kết quả thành độ chính xác thấp hơn khi gán nó cho biến có độ chính xác thấp hơn. Trong tiêu chuẩn C ban đầu, ví dụ, trình tự:

float a = 16777216, b = 0.125, c = -16777216;
float d = a+b+c;

sẽ thúc đẩy abđể double, thêm chúng, thúc đẩy cđể double, thêm nó, và sau đó lưu trữ kết quả làm tròn đến float. Mặc dù trong nhiều trường hợp, trình biên dịch tạo mã sẽ thực hiện các thao tác trực tiếp trên loại nhanh hơn float, đơn giản hơn là có một tập các thói quen dấu phẩy động chỉ hoạt động trên loại double, cùng với các thường trình để chuyển đổi thành / từ float, hơn là có các bộ thói quen riêng để xử lý các hoạt động trên floatdouble. 8087 được thiết kế xoay quanh phương pháp tiếp cận số học, thực hiện tất cả các hoạt động số học bằng cách sử dụng loại dấu phẩy động 80 bit [80 bit có thể được chọn vì:

  1. Trên nhiều bộ xử lý 16 và 32 bit, hoạt động nhanh hơn với mantissa 64 bit và số mũ riêng biệt hơn là hoạt động với giá trị chia một byte giữa mantissa và lũy thừa.

  2. Rất khó để thực hiện các tính toán chính xác đến độ chính xác đầy đủ của các loại số mà người ta đang sử dụng; nếu một người đang cố gắng tính toán một cái gì đó như log10 (x), thì việc tính kết quả chính xác trong vòng 100ulp của loại 80 bit sẽ dễ dàng và nhanh hơn so với tính toán một kết quả chính xác trong vòng 1ulp của 64 bit loại và làm tròn kết quả trước thành độ chính xác 64 bit sẽ mang lại giá trị 64 bit chính xác hơn giá trị sau.

Thật không may, các phiên bản tương lai của ngôn ngữ đã thay đổi ngữ nghĩa về cách các loại dấu phẩy động nên hoạt động; trong khi ngữ nghĩa 8087 sẽ rất tốt nếu các ngôn ngữ đã hỗ trợ chúng một cách nhất quán, nếu kiểu trả về các hàm F1 (), f2 (), v.v. float, nhiều tác giả trình biên dịch sẽ tự lấy nó để tạo long doublebí danh cho loại kép 64 bit thay vì loại 80 bit của trình biên dịch (và không cung cấp phương tiện nào khác để tạo biến 80 bit) và để tự ý đánh giá một cái gì đó như:

double f = f1()*f2() - f3()*f4();

theo bất kỳ cách nào sau đây:

double f = (float)(f1()*f2()) - (extended_double)f3()*f4();
double f = (extended_double)f1()*f2() - (float)(f3()*f4());
double f = (float)(f1()*f2()) - (float)(f3()*f4());
double f = (extended_double)f1()*f2() - (extended_double)f3()*f4();

Lưu ý rằng nếu f3 và f4 trả về các giá trị tương ứng là F1 và f2, thì biểu thức ban đầu sẽ trả về 0 rõ ràng, nhưng nhiều biểu thức sau có thể không. Điều này dẫn đến việc mọi người lên án "độ chính xác thêm" của 8087 mặc dù công thức cuối cùng thường vượt trội hơn so với thứ ba và - với mã sử dụng loại kép mở rộng một cách thích hợp - hiếm khi kém hơn.

Trong những năm qua, Intel đã phản ứng với xu hướng ngôn ngữ (không may IMHO) về việc buộc các kết quả trung gian phải được làm tròn theo độ chính xác của toán hạng bằng cách thiết kế bộ xử lý sau của chúng để ưu tiên hành vi đó, gây bất lợi cho việc sử dụng mã cao hơn độ chính xác trên các tính toán trung gian.


Lưu ý rằng bạn đã có câu trả lời ( ở trên ) trong bài viết này. Có phải chúng là những câu trả lời có thể / nên được hợp nhất thành một?

@MichaelT: Tôi không nghĩ vậy - một cái bao gồm thiết kế ngăn xếp, và cái kia bao gồm ngữ nghĩa dấu phẩy động.
supercat

Chỉ đảm bảo. Cá nhân, tôi tin rằng sẽ có thể đưa ra một câu trả lời mạnh mẽ hơn (sử dụng các tiêu đề để phân tách các phần), nhưng đó là điều tôi đảm nhận. Bạn có thể vẫn muốn sử dụng các tiêu đề để xác định rõ ràng ở đầu mỗi phần câu trả lời ( ## How the stack changed the processor## How floating point changed the processor) để mọi người có thể hiểu được suy nghĩ đúng đắn của mình khi đọc nó và ít có khả năng nghĩ rằng bạn đãng trí khi trả lời hoặc đăng lại cùng (r tương tự) câu trả lời.

@MichaelT: Hai câu trả lời đủ khác nhau mà tôi nghĩ rằng chúng nên được bỏ phiếu riêng. Mặc dù 80486 đã hấp thụ các chức năng được thực hiện trước đây bởi 8087/80287/80387, 8086 và 8087 được thiết kế dưới dạng các chip riêng biệt với kiến ​​trúc gần như độc lập. Mặc dù cả hai đều chạy mã từ một luồng lệnh chung, được xử lý bằng cách xử lý 8086 một số chuỗi byte nhất định như các yêu cầu để tạo các yêu cầu đọc / ghi địa chỉ trong khi bỏ qua bus dữ liệu và 8087 bỏ qua mọi thứ khác đang diễn ra.
supercat
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.