언어가 CPU 디자인에 어떤 영향을 미쳤습니까? [닫은]


44

우리는 하드웨어가 컴파일 된 이진 코드만을 볼 때 프로그램이 어떤 언어로 작성되었는지는 신경 쓰지 않는다고하지만 종종 이것이 사실은 아닙니다. 예를 들어 겸손한 Z80을 생각해보십시오. 8080 명령어 세트의 확장 기능에는 CPIR과 같은 명령어가 포함되어 있습니다. CPIR은 C 스타일 (NULL로 끝나는) 문자열을 스캔하는 데 유용합니다 (예 : 수행) strlen(). 설계자는 C 길이의 프로그램이 Pascal과 달리 (길이가 헤더에있는) C 프로그램이 설계에 사용될 가능성이 있음을 식별해야합니다. 또 다른 고전적인 예는 Lisp Machine 입니다.

다른 예는 무엇입니까? 예를 들어 특정 프로세서가 특정 언어의 규칙을 선호하게 만드는 명령어, 레지스터의 수 및 유형 , 주소 지정 모드? 나는 특히 같은 가족의 개정에 관심이 있습니다.


3
Z-80에도 LDIR 명령어가 있다는 것을 잊지 마십시오. 길이를 알고있을 때 문자열을 복사 할 때 매우 유용합니다 (길이가 헤더에 저장된 파스칼에서와 같이).
TMN

27
1. Z-80은 K & R 초판 3 년 전에 유닉스와 C가 몇몇 컴퓨터에서 모호한 운영 체제와 언어 인 1975 년에 설계되었습니다. 2. 문자열 길이가 "헤더 안에"있어야한다는 파스칼은 없습니다. 3. 당시 주요 마이크로 컴퓨터 OS 인 CP / M의 문자열은 '\ 0'이 아닌 '$'문자로 종료되었습니다. CPIR은 모든 문자를 검색 할 수 있습니다. 4. CPIR은 CPDR (뒤로 검색) 및 기타 -IR 및 -DR 명령어와 일치합니다. 결론 : CPIR은 C 프로그래밍 언어와 관련이 없습니다. 바이트 검색 명령어 일뿐입니다.
librik

4
C가 강요하는 것 중 가장 큰 것 (그리고 하드웨어 디자이너에게 가장 성가신 것 중 하나)은 바이트 주소 지정입니다. 이러한 혐오없이 CPU가 더 단순하고 빨 랐을 것입니다.
SK- 로직

1
@ SK-logic : POSIX 표준에는 바이트 주소 지정이 필요하지만 C 표준에는 그렇지 않습니다. sizeof(int)1 과 같은 모든 구현 은 형식의 모든 값을 보유 할 수 있어야 char하므로 형식 을 서명 int해야합니다 char. 나는 기계에 대한 코드를 작성 곳했습니다 charint16 비트 부호 모두 정수; 가장 큰 어려움은 형식 변환에 공용체를 사용할 수 없으며 많은 바이트를 효율적으로 저장하려면 수동 포장 및 포장 풀기가 필요하다는 것입니다. 이러한 문제는 C에서 sizeof (int) == sizeof (long) 일 가능성에 비해 사소합니다.
supercat

2
... 즉, 두 unsigned int값 의 차이를 견딜 수있는 표준 유형이 없음을 의미 합니다. C99는 이러한 상황을 개선했지만 C99 이전에는 음의 값을 유형의 값과 비교할 수있는 안전한 단일 단계 방법 unsigned int이 없었습니다 (비교하기 전에 숫자가 음수인지 테스트해야 함).
supercat

답변:


20

기존 답변은 ISA 변경에 중점을 둡니다 . 다른 하드웨어 변경 사항도 있습니다. 예를 들어 C ++은 일반적으로 가상 호출에 vtable을 사용합니다. 인텔은 펜티엄 M부터 가상 함수 호출을 가속화하는 "간접 분기 예측기"구성 요소를 갖추고 있습니다.


6
Berkeley RISC 아키텍처에는 "레지스터 파일"이라는 개념이 포함되어 있으므로 스택에 함수를 "유출"레지스터로 만드는 대신 각 함수에 8 개의 레지스터 블록이 제공되었습니다. 이것은 짧은 메소드에 대한 많은 메소드 호출로 구성되는 경향이 있기 때문에 객체 지향 코드를 상당히 가속화했습니다.
TMN

1
이것은 유효한 예가 아닙니다. 은 "함수 포인터의 표는"디자인되고 또한 Windows에서 DLL 가져 오기 및 내보내기를 통해, 예를 들어, 많은 동적 연결 시나리오에서 사용하고, 또한 C 프로그램에 사용됩니다. 프로세서가 특정 용도에 최적화되어 있음을 보여줄 수는 있지만 언어별로 다릅니다.
DeadMG

@DeadMG : 다른 경우에도 혜택이있었습니다. 그러나 C ++가 대중화 될 때까지 CPU 디자인은 영향 을받지 않았습니다 . 그리고 그것은 제기 된 질문이었습니다. 마찬가지로 TMN에는 레지스터 파일에 대한 요점이 있습니다. 어셈블리에는 분명한 기능 개념이 없었습니다. 오늘날 우리가 일반적으로 이해하는 함수는 Algol 60으로 거슬러 올라갑니다. 따라서 Algol 60은 CPU 레지스터 파일 디자인에 영향을 미쳤다고 말할 수 있습니다.
MSalters

14

인텔 8086 명령어 세트에는 반환 주소를 팝한 스택 포인터에 값을 추가하는 "ret"변형이 포함되어 있습니다. 이것은 함수 호출자가 함수 호출을하기 전에 스택으로 인수를 밀어 넣고 그 후에 튀어 나오는 많은 파스칼 구현에 유용합니다. 루틴이 예를 들어 4 바이트 단위의 매개 변수를 승인하면 스택을 정리하기 위해 "RET 0004"로 끝날 수 있습니다. 이러한 명령어가 없으면 호출 규칙에 따라 리턴 주소를 레지스터로 팝하고 스택 포인터를 업데이트 한 다음 해당 레지스터로 점프해야합니다.

흥미롭게도, 원래 Macintosh의 대부분의 코드 (OS 루틴 포함)는 68000의 지침이 없어도 Pascal 호출 규칙을 사용했습니다.이 호출 규칙을 사용하면 일반적인 호출 사이트에서 2-4 바이트의 코드가 절약되었지만 추가 코드가 필요했습니다. 매개 변수를 사용하는 모든 함수의 반환 사이트에 4-6 바이트의 코드가 있습니다.


이것에 ENTER대응하는 것도 있습니다 RET n...
herby

1
@ 허비 : ENTER원래 8086에 존재 하지 않았다고 생각 합니다. 이후 프로세서와 함께 제공됩니다. BP 기반 어드레싱 모드는 스택 된 매개 변수와 프레임 포인터를 통해 액세스되는 로컬을 사용하도록 명확하게 설계되었습니다. 이 규칙은 여러 가지면에서 흥미 롭습니다. 특히 (1) 순수 어셈블리 언어 코드가 스택보다 레지스터의 값을 사용하는 것이 더 적합하지만 (2) [SP +에 비해 [BP + nn]의 장점은 nn] 주소 지정은 스택보다 내용에 액세스하는 어셈블리 언어 프로그램보다 더 중요합니다.
supercat

... 필기 조립 코드 용. 컴파일러는 일반적으로 생성 된 모든 명령어에 대해 SP와 BP의 비교 방법을 알고 있습니다. 예를 들어 SP가 BP-8이면 컴파일러가 [SP + 20]보다 [BP + 12]를 처리하기가 쉽지 않습니다. 다시 컴파일 할 때 컴파일러가 코드 블록 주위에 다른 PUSH / POP를 추가해야하는 경우 SP 기반 오프셋을 적절하게 조정할 수 있습니다. 반면에 수작업으로 작성하는 어셈블리에서 PUSH / POP를 추가하면 코드를 수정해야 할 가능성이 높습니다. 따라서 프레임 포인터는 기본적으로 고수준 / asm 코드를 결합하는 데 도움이됩니다.
supercat

재 컴파일없이 코드를 재사용 할 가능성도 BP 주소 지정에있어 약간의 유용성 지점 일 수 있습니다. 그리고 하나님은 BP 주소 정렬 기준 ...이기 때문에 BP 해결 지침, SP는 사람들을 해결보다 회로에없는 빠른 경우 알
herby

3
@herby : 실제로 컴파일러가 일반적으로 프레임 포인터를 사용한 이유는 디버깅과 많은 관련이 있다고 생각합니다. 이러한 규칙을 사용하지 않는 프로그램을 디버그하려면 컴파일러가 모든 명령어에 대한 SP-BP 오프셋을 나열하는 파일을 생성하고 디버거를 사용해야합니다. 이러한 자세한 메타 데이터는 오늘날 일반적이며 가비지 수집 언어를 실용화하는 데 필수적인 부분이지만 필요한 RAM 용량은 30 년 전에는 받아 들일 수 없었습니다.
supercat

10

하나의 예는 모두 갖고, MIPS이다 addaddu트래핑 각각 오버 플로우를 무시하고있다. (또 subsubu.) 그것은 에이다 같은 언어에 대한 명령의 첫 번째 유형을 필요로 (내 생각 - I've 실제로 에이다 불구을 사용하지 않음) 명시 적으로 오버 플로우와 오버 플로우를 무시 C와 같은 언어에 대한 두 번째 유형되는 거래.

올바르게 기억한다면 실제 CPU에는 오버플로를 추적하기 위해 ALU에 추가 회로가 있습니다. 사람들이 관심을 가진 유일한 언어가 C라면, 이것이 필요하지 않을 것입니다.


관련이 있는지 확실하지 않지만 해당 명령어는 안전한 메모리 할당과 같은 다른 상황에서도 유용합니다. 예를 들어 nmemb*size+offset바이트 를 할당 하고 오버플로가 발생하지 않도록해야합니다.
NikiC

@ NikC : 나는 addusubu지침 ( 오버플로를 확인 하지 않는 것)이 C를 행복하게하기 위해 추가 된 것이라고 생각했습니다. 물론, 나는 정말로 모른다-우리는 강의에서 막연하게 다루었 고 건축 전문가는 분명하지 않다. : P.
Tikhon Jelvis

오 예, 다른 방법으로 생각하고있었습니다. 죄송합니다 : /
NikiC

8

Burroughs 5000 시리즈는 ALGOL을 효율적으로 지원하도록 설계되었으며 Intel의 iAPX-432는 Ada를 효율적으로 실행하도록 설계되었습니다. Inmos Transputer의 언어는 Occam입니다. Parallax "Propeller"프로세서는 자체 BASIC 변형을 사용하여 프로그래밍하도록 설계되었다고 생각합니다.

언어는 아니지만 VAX-11 명령 세트에는 프로세스 컨텍스트를로드하는 단일 명령이 있습니다.이 명령은 VMS 디자인 팀의 요청에 따라 설계되었습니다. 세부 사항은 기억 나지 않지만 ISTR은 구현하는 데 많은 지침이 필요하므로 예약 가능한 프로세스 수에 심각한 상한을 두었습니다.


이러한 디자인이 특히 적합한 이유는 무엇입니까? 예를 들어, Ada는 iAPX의 어떤 기능을 특히 활용할 수 있습니까?
Gaius

IAPX-432의 Ada 대상이 실패한 디자인을 다른 것보다 아직 큰 기대치를 가지고 무언가에 부착함으로써 더 많은 노력을 기울이고 있다고 ISTR은 말합니다.
AProgrammer

@AProgrammer : iAPX-432는 처음부터 Ada를 사용하도록 설계되었습니다. 나는 인텔이 명령어 세트를 출판하지 않고 어셈블리 언어 프로그래밍을 방해하고 사람들이 모든 것을 위해 Ada를 사용하도록 강요하지 않았다는 소문도 떠올랐다.
TMN

1
Intel의 432 프로젝트 인 @TMN은 1975 년에 시작되어 1981 년에 소개되었습니다 (Wikipedia). Ironman (Ada의 최종 요구 사항)은 1977 년 1 월에 출판되었으며 1979 년 5 월에 녹색이 선택되어 수정되었으며 최종 결과는 1980 년 7 월에 군사 표준으로 발표되었습니다. iAPX-432는 Ada를 사용하기 시작했습니다. (대체 대안을 찾기 시작했을 때 일반적인 단점이있는 늦고 전형적인 "의미 적 차이를 좁히는"프로세서입니다 .Ada 프로세서로 마케팅하는 것은 실패한 디자인을 저장하기위한 임시적인 것이 었습니다. )
AProgrammer

1
@AProgrammer : 흠, 당신이 옳은 것 같습니다. 나는 432의 수석 아키텍트로부터이 논문 을 보았고 요약에서 그는 "432가 Ada를 실행하도록 설계 되었기 때문에 아키텍처와 언어의 이러한 긴밀한 일치는 발생하지 않았다"고 말했다. 오래된 432 권의 책을 발굴하여 그 내용을 읽어야합니다.
TMN

8

지금까지 아무도 언급하지 않은 것 중 하나는 (기본 언어와 거의 관련이없는) 컴파일러 최적화의 발전이 CISC 명령어 세트 (사람이 코딩하도록 설계되어 있음)에서 RISC 명령어 세트 (대부분은 컴파일러에 의해 코딩되도록 설계되었습니다.)


5

Motorola 68000 제품군 은 CPU를 통한 데이터 복사를 매우 효율적이고 컴팩트하게 만드는 자동 증분 어드레스 모드 를 도입했습니다 .

[업데이트 된 예]

이것은 68000 어셈블러에 영향을 미치는 일부 C ++ 코드입니다.

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

기존 어셈블러에서 구현 (의사 코드, 68000 어셈블러 명령을 잊어 버렸습니다)

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

새로운 adressmode를 사용하면

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

루프 당 4 개 대신 2 개의 명령어 만.


1
이것은 특정 언어의 규칙에 어떤 영향을 받았습니까?
Gaius

업데이트 된 예 참조
k3b

아, 68010에서 DBxx 루프 최적화를 생각 나게한다.
Gaius

7
사실, 나는 당신이 이것을 거꾸로 가지고 있다고 생각합니다. 자동 생성 어드레싱은 PDP-11 명령 세트의 일부였으며 이는 C의 설계에 영향을 미쳤습니다.
TMN

5

IBM Z 시리즈 메인 프레임은 1960 년대 IBM 360의 후손입니다.

COBOL 및 Fortran 프로그램의 속도를 높이기 위해 특별히 작성된 몇 가지 지침이있었습니다. 전형적인 예는 BXLE– Fortran for루프 또는 PERFORM VARYING x from 1 by 1 until x > n단일 명령어로 캡슐화 된 COBOL 의 대부분인 "지수가 낮거나 같음"입니다 .

COBOL 프로그램에서 공통으로 사용되는 고정 소수점 10 진 산술을 지원하기 위해 팩형 10 진 명령어 제품군이 있습니다.


나는 당신이 자손 을 의미한다고 생각합니다 .
Clockwork-Muse

@ X- 제로-죄송합니다! 이른 아침, 시스템 등에 충분한 카피 엔이 ​​부족합니다.
James Anderson

1
TI 32050 DSP의 블록 반복 명령이 더 흥미 롭습니다. 피연산자는 루프의 마지막 명령 다음에 오는 명령의 주소입니다. 루프 카운트 레지스터를로드 한 다음 블록 반복 명령을 수행하면 지정된 횟수만큼 대상까지 명령이 반복됩니다 (포함하지는 않음). FORTRAN DO루프를 매우 연상시킵니다 .
supercat

@supercat 그 이름에 걸 맞는 모든 DSP에는 제로 오버 헤드 루프, 단일 명령어 곱셈 누적 및 비트 반전 주소 지정 모드의 세 가지 기능이 있습니다. Man으로 알려진 거의 모든 DSP 알고리즘은 루프를 사용합니다. 가장 일반적인 두 가지 알고리즘은 곱셈 누적 루프 인 FIR 필터와 비트 반전 주소 지정이 중요한 FFT입니다. 많은 DSP는 one-instruction radix-2 FFT 버터 플라이 연산 또는 one-instruction 버터 플라이를 만드는 데 사용할 수있는 이중 곱셈 / 추가를 포함합니다.
John R. Strohm

@ JohnR.Strohm : 내가 본 모든 DSP에는 반복 곱하기 누산이 포함되어 있지만 모두 더 일반화 된 제로 오버 헤드 루프를 포함하는 것은 아닙니다. 실제로, 왜 그런 루프가 많은 "기존 프로세서"코드에서도 유용하기 때문에 왜 "DSP"기능으로 간주되어야하는지 잘 모르겠습니다.
supercat

3

초기 인텔 CPU에는 다음과 같은 기능이 있으며 현재 64 비트 모드에서 더 이상 사용되지 않습니다.

  • ENTER, LEAVE 및 RET nn 명령어 [초기 매뉴얼에는 블록 구조 언어 (예 : 중첩 프로 시저를 지원하는 파스칼)에 대해 소개 된 내용이 명시되어 있음)
  • BCD 산술 속도를 높이기위한 지침 (AAA, AAM 등); x87의 BCD 지원
  • 카운트 루프 구현을위한 JCXZ 및 LOOP 명령어
  • INTO, 산술 오버플로에 트랩 생성 (예 : Ada)
  • 테이블 조회를위한 XLAT
  • 배열 경계를 확인하기위한 BOUND

많은 CPU의 상태 레지스터에있는 부호 플래그는 부호있는 및 부호없는 산술을 쉽게 수행하기 위해 존재합니다.

SSE 4.1 명령어 세트는 카운트 및 제로 종료 (PCMPESTR 등) 문자열 처리 명령어를 소개합니다.

또한 여러 시스템 수준 기능이 컴파일 된 코드 (세그먼트 제한 검사, 매개 변수 복사를 통한 호출 게이트 등)의 안전을 지원하도록 설계되었다고 생각할 수 있습니다.


3

일부 ARM 프로세서 (주로 모바일 장치의 프로세서)에는 하드웨어 JVM 인터프리터 인 Jazelle 확장이 포함됩니다. Java 바이트 코드를 직접 해석합니다. Jazelle을 인식하는 JVM은 하드웨어를 사용하여 실행 속도를 높이고 많은 JIT를 제거 할 수 있지만, 바이트 코드를 칩에서 해석 할 수없는 경우 소프트웨어 VM으로의 대체는 여전히 보장됩니다.

이러한 장치가있는 프로세서에는 BXJ 명령어가 포함되어 프로세서를 특수 "Jazelle 모드"로 설정하거나 장치 활성화에 실패한 경우 일반 분기 명령어로 해석됩니다. 장치는 ARM 레지스터를 재사용하여 JVM 상태를 유지합니다.

Jazelle 기술의 후속 제품은 ThumbEE입니다


2

내가 아는 한 이것은 과거에 더 흔했습니다.

질문의 세션 제임스 고슬링 (James Gosling)이 JVM 바이트 코드와 더 나은 거래 수있는 하드웨어를 만들려고 노력하는 사람이었다, 그러나이 사람들이 아마 컴파일 (공통 "일반적인"인텔의 x86와 함께 할 수있는 방법을 찾을 것이라고 말했다되는이 영리한 방식으로 바이트 코드).

그는 일반 대중 칩 (인텔 등)을 사용하면 제품에 막대한 금액의 돈을 버는 대기업이 있기 때문에 이점이 있다고 언급했다.

비디오 확인 가치가 있습니다. 그는 19 분 또는 20 분에 이에 대해 이야기합니다.



2

인텔 iAPX CPU는 특히 객체 지향 언어에 대한 설계되었습니다. 그래도 해결되지 않았습니다.

iAPX 432 ( 인텔 고급 프로세서 아키텍처는 ) 세 집적 회로의 집합으로 1981 년에 도입 된 인텔 최초의 32 비트 마이크로 프로세서 설계했다. 1980 년대 인텔의 주요 디자인으로 많은 고급 멀티 태스킹 및 메모리 관리 기능을 구현했습니다. 따라서이 디자인을 마이크로 메인 프레임 이라고합니다 .

iAPX 432는 "고급 언어로 완전히 프로그래밍되도록 설계되었습니다"Ada 를 기본 으로하며 하드웨어 및 마이크로 코드 에서 직접 객체 지향 프로그래밍가비지 수집을 지원 했습니다 . 다양한 데이터 구조 에 대한 직접적인 지원 은 iAPX 432의 최신 운영 체제가 일반 프로세서보다 훨씬 적은 프로그램 코드를 사용하여 구현 될 수 있도록하기위한 것입니다. 이러한 특성과 특징으로 인해 하드웨어 및 마이크로 코드 설계는 그 당시 대부분의 프로세서, 특히 마이크로 프로세서보다 훨씬 더 복잡했습니다.

인텔의 엔지니어들은 당시의 반도체 기술을 사용하여 디자인을 매우 효율적인 첫 번째 구현으로 변환 할 수 없었습니다. 조기 Ada 컴파일러의 최적화 부족과 함께, 이는 느리지 만 고가의 컴퓨터 시스템에 기여했으며, 동일한 클록 주파수 (1982 년 초)에서 새로운 80286 칩 속도의 약 1/4 속도로 일반적인 벤치 마크를 수행했습니다.

다소 낮은 프로파일과 저렴한 가격의 8086 라인에 대한 초기 성능 차이는 아마도 인텔이 후자 (나중에 x86)를 iAPX 432로 교체하려는 주된 이유 일 것입니다. 엔지니어들은 차세대 설계를 개선 할 수있는 방법을 찾았지만 iAPX 432 기능 아키텍처 는 이제 단순화 된 지원이 아니라 구현 오버 헤드로 간주되기 시작했습니다.

iAPX 432 프로젝트는 인텔의 상업적 실패였습니다 ...


논문을 읽으면 디자인의 많은 측면이 오늘날 인기있는 객체 지향 프레임 워크에 유용 할 수 있습니다. 32 비트 object-id와 32 비트 오프셋의 조합을 사용한 아키텍처는 대부분의 경우 오브젝트 ID가 모두 64 비트 인 것보다 캐싱 성능을 향상시킬 수 있습니다 (대부분의 경우 수십억 개의 오브젝트를 사용하는 애플리케이션은 더 크고 더 큰 것을 사용하여 더 나은 서비스를 제공합니다. 하나의 객체에 수십억 바이트를 저장하는 것이 더 작은 객체로 세분화되는 것이 더 좋습니다.
supercat

1

68000에는 많은 언어가 예상하는 단일 명령으로 여러 레지스터를 스택에 푸시하는 데 가장 적합한 MOVEM이있었습니다.

코드 전체에서 JSR (Jump SubRoutine) 앞에 MOVEM (MOVE Multiple)이 있으면 C 준수 코드를 처리하고 있다는 것을 알 수 있습니다.

MOVEM을 사용하면 대상 레지스터의 자동 증분을 허용하여 각 사용이 대상에 계속 스태킹되거나 자동 감소의 경우 스택에서 제거 할 수 있습니다.

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


1

Atmel의 AVR 아키텍처는 완전히 C부터 프로그래밍하기에 적합하도록 처음부터 설계되었습니다. 예를 들어이 애플리케이션 노트는 더 자세히 설명합니다.

IMO 이것은 로켓과 밀접한 관련이 있습니다 .4kids의 탁월한 답변 . 직접 PIC 어셈블러는 직접 어셈블러 프로그래밍 (총 40 명령)을 위해 개발되었으며, 이후 가족은 C를 타겟팅합니다.


1

8087 숫자 형 코 프로세서가 설계되었을 때 언어에서 모든 부동 소수점 연산을 최고 정밀도 유형을 사용하여 정밀도가 낮은 변수에 할당 할 때 결과를 낮은 정밀도로 반올림하는 것이 일반적이었습니다. 예를 들어 원래 C 표준에서 시퀀스는 다음과 같습니다.

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

촉진 것입니다 abdouble홍보를 추가 cdouble결과가 반올림 저장 한 다음 추가하고 float. 컴파일러가 타입에 대해 직접 연산을 수행하는 코드를 생성하는 것이 더 빠를지라도 float, 타입 에 대해서만 작동하는 부동 소수점 루틴 세트 double를 변환하는 루틴과 함께 사용 하는 것이 더 간단했습니다. 에서 float의 작업을 처리하는 루틴의 별도의 세트를 가지고하는 것보다, float하고 double. 8087은 80 비트 부동 소수점 유형 [80 비트가 다음과 같은 이유로 선택되었을 수 있음]을 사용하여 모든 산술 연산을 수행하는 산술 접근 방식을 중심으로 설계되었습니다.

  1. 많은 16 비트 및 32 비트 프로세서에서 가수와 지수 사이에서 바이트를 나누는 값으로 작업하는 것보다 64 비트 가수와 별도의 지수로 작업하는 것이 더 빠릅니다.

  2. 사용하는 숫자 유형의 전체 정밀도에 정확한 계산을 수행하는 것은 매우 어렵습니다. 예를 들어 log10 (x)와 같은 것을 계산하려는 경우 64 비트의 1ulp 내에서 정확한 결과를 계산하는 것보다 80-bit 유형의 100ulp 내에서 정확한 결과를 계산하는 것이 더 쉽고 빠릅니다. 이전 결과를 64 비트 정밀도로 반올림하면 후자보다 정확한 64 비트 값이 생성됩니다.

불행히도, 이후 버전의 언어는 부동 소수점 유형이 작동하는 방식의 의미를 변경했습니다. 만약 언어가 일관되게 언어를 지원했다면 8087 의미론은 매우 좋았을 것인데, 함수 f1 (), f2 () 등이 type을 반환 float한다면, 많은 컴파일러 제작자들이 long double64 비트 double 형의 별칭 을 만들기 위해 그것을 취할 것입니다. 컴파일러의 80 비트 유형이 아니라 (80 비트 변수를 만드는 다른 방법을 제공하지 않음) 다음과 같이 임의로 평가하십시오.

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

다음과 같은 방법으로 :

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();

f3 및 f4가 각각 f1 및 f2와 동일한 값을 반환하면 원래 식은 분명히 0을 반환해야하지만 후자 식 중 많은 식은 그렇지 않을 수 있습니다. 마지막 공식이 일반적으로 세 번째보다 우수하지만 확장 된 이중 유형을 적절하게 사용하는 코드를 사용하면 거의 열등하지 않더라도 8087의 "초정밀"을 비난하는 사람들로 이어졌습니다.

그 사이에 인텔은 그 이후의 프로세서를 설계하여 더 높은 성능을 사용함으로써 이익을 얻을 수있는 코드를 손상 시키도록 후반 프로세서를 설계함으로써 중간 결과를 피연산자의 정밀도로 반올림하도록하는 언어 (IMHO 불행한 경향) 추세에 응답했습니다. 중간 계산의 정밀도.


이 게시물에 이미 의 답변 이 있습니다. 그들은 하나로 합쳐질 수있는 대답입니까?

@MichaelT : 그렇게 생각하지 않습니다. 하나는 스택 디자인을 다루고 다른 하나는 부동 소수점 의미를 다루고 있습니다.
supercat

그냥 확인하십시오. 개인적으로 (섹션을 구분하기 위해 헤더를 사용하여) 하나의 더 강력한 대답을 할 수 있다고 생각하지만 그 점을 이해해야합니다. 아직 명확하게 상단에 식별에 헤더를 사용하려면하실 수 있습니다 무엇 각각의 응답 부분 주소 ( ## How the stack changed the processor## How floating point changed the processor) 그래서 사람들은 그것을 읽을 때 그는 적절한 마음이 설정 INT 얻을 당신이 중 하나에 응답하거나 다시 게시에 마음 결석라고 생각 가능성이 적은 수 같은 (r 비슷한) 답변.

@MichaelT : 두 가지 답변이 충분히 분리되어있어 별도로 투표해야한다고 생각합니다. 80486은 8087/80287/80387에 의해 이전에 수행 된 기능을 흡수했지만 8086 및 8087은 거의 독립적 인 아키텍처를 가진 별도의 칩으로 설계되었습니다. 둘 다 공통 명령 스트림에서 코드를 실행했지만 8086이 특정 바이트 시퀀스를 주소 읽기 / 쓰기 요청을 생성하는 요청으로 처리하여 데이터 버스를 무시하고 8087이 진행중인 다른 모든 것을 무시하도록하여 처리되었습니다.
supercat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.