32 비트 시스템에서 80 비트 부동 소수점을 어떻게 사용할 수 있습니까? [복제]


13

32 비트 시스템은 명백한 32 비트 제한 때문에 2 ^ 33 숫자를 관리 할 수 ​​없기 때문에 어떻게 80 비트 부동 소수점 숫자를 관리 할 수 있습니까?

"80 비트"가 필요합니다 ...


8
64 비트 부동 소수점 숫자와 같은 방식입니다. 3 개 또는 (2) 32 비트 레지스터를 사용합니다. 80 비트 부동 소수점 숫자는 표준 크기가 아니기 때문에 실제로는 80 비트 만 사용되는 96 비트 숫자입니다.
Ramhound

5
플랫폼 bittedness에 대해 걱정할 때 다른 사람들이 말했듯이 CPU의 내부 작동 및 시스템에서 명령이 실행되는 방식에 대해 걱정합니다. IEEE754 숫자는 일반적으로 CPU의 FPU 실행 단위에서 직접 처리 할 수 ​​있지만 128 비트 숫자는 응용 프로그램이 평가하는 값의 의미를 집계 할 수 있도록 프로그래밍 된 여러 명령을 사용해야합니다. 번호 처리를 응용 프로그램에 맡깁니다.
Frank Thomas

2
@ Ƭᴇcʜιᴇ007하지 꽤 잘 속는 사람 하나. 하나는 숫자와 텍스트 / ASCII 표현의 차이점에 관한 것입니다. 그러나 그 대답 중 일부는 이것을 해결할 수도 있습니다.
Bob

3
거의 모든 최신 컴퓨터에서 부동 소수점은 별도의 프로세서 (일반적으로 주 프로세서와 동일한 칩에 있음)로 처리됩니다. 이러한 모든 프로세서는 80 비트를 처리하는 방법을 알고 있습니다 (일부는 다른 프로세서보다 훨씬 빠릅니다). ( 그리고 프로세서의 "폭"은 어쨌든 허구입니다. )
Daniel R Hicks

6
@Ramhound : 아니요, 80 비트는 8087 특성이며 1 개의 FP 레지스터를 사용합니다. 확실히 96 비트 숫자가 아닙니다.
MSalters

답변:


35

32 비트 CPU의 의미 중 하나는 레지스터의 너비가 32 비트라는 것입니다. 이것은 64 비트 숫자를 처리 할 수 ​​없다는 것을 의미하지 않으며, 먼저 하위 32 비트 반을 처리 한 다음 상위 32 비트 반 초를 처리해야합니다. (CPU에 캐리 플래그 가있는 이유 입니다.) CPU가 더 넓은 64 비트 레지스터에 값을로드 할 수있는 것보다 느리지 만 여전히 가능합니다.

따라서 시스템의 "비트 니스"는 프로그램이 처리 할 수있는 숫자의 크기를 반드시 제한하지는 않습니다. CPU 레지스터에 맞지 않는 연산을 여러 연산으로 항상 분할 할 수 있기 때문입니다. 따라서 작업 속도가 느려지고 더 많은 메모리를 사용하고 (메모리를 "스크래치 패드"로 사용해야하는 경우) 프로그래밍하기가 더 어렵지만 작업은 여전히 ​​가능합니다.

그러나 CPU의 부동 소수점 부분에는 자체 레지스터가 있고 폭이 80 비트이므로 Intel 32 비트 프로세서 및 부동 소수점과 같은 것은 중요하지 않습니다. (초기 x86의 역사에서 부동 소수점 기능은 별도의 칩이었으며 80486DX부터 CPU에 통합되었습니다.)


@Breakthrough의 대답은 이것을 추가하도록 영감을주었습니다.

FPU 레지스터에 저장된 부동 소수점 값은 이진 정수 값과 매우 다른 방식으로 작동합니다.

부동 소수점 값의 80 비트는 가수와 지수로 나뉩니다 (항상 2 인 부동 소수점 숫자에 "기본"도 있습니다). 가수에는 유효 숫자가 포함되며 지수는 유효 숫자의 크기를 결정합니다. 따라서 다른 레지스터에 "오버플로"가 없습니다. 숫자가 가수에 비해 너무 커지면 지수가 증가하고 정밀도가 떨어집니다. 즉, 정수로 변환하면 소수점 이하 자릿수가 손실됩니다. 이것이 부동 소수점이라고하는 이유입니다.

지수가 너무 크면 부동 소수점 오버플로가 발생하지만 지수와 가수가 묶여 있기 때문에 다른 레지스터로 쉽게 확장 할 수 없습니다.

나는 그 중 일부에 대해 부정확하고 잘못 될 수 있지만 그것이 그 요점이라고 생각합니다. (이 Wikipedia 기사 는 위의 내용을 간결하게 보여줍니다.)

CPU의 전체 "부동 소수점"부분은 자체 세계에 있으므로 완전히 다르게 작동하는 것이 좋습니다. 특수 CPU 명령어를 사용하여 액세스하는 등의 작업이 가능합니다. 또한, 문제의 시점을 향해서, 그것은 별도이기 때문에 FPU의 비트는 기본 CPU의 비트와 밀접하게 결합되지 않습니다.


4
내 영감으로 추가 한 모든 것이 정확하므로 걱정할 필요가 없습니다.) 언급해야 할 점은 부동 소수점 단위가있는 기본 CPU 명령어를 사용할 수 있지만 소프트웨어에서 부동 소수점 연산을 수행 할 수 있음 또는 정수 수학 연산). 충분한 메모리가 주어진 시점까지 확장하려면 소프트웨어 알고리즘 / 라이브러리 (일반적으로 사용되는 하나는 GNU 다중 정밀도 임)를 사용하여 임의의 정밀도 숫자 (이 경우 고정 64 비트 또는 80 비트와 반대)를 가질 수도 있습니다. 도서관 ).
획기적인

1
Nitpick : 최초의 인텔 통합 FPU는 80386이 아니라
80486DX에있었습니다.

2
@ markzzz : 필요한 경우 아무것도 없습니다. 핵 비축량을 평가하기 위해 16 비트 수레를 사용하여 원자 폭탄을 시뮬레이트하는 것은 결과에 확신을 갖기에 충분히 정확하지 않기 때문에 미친 짓입니다. 어떤 경우에 32 비트가 필요합니다 (그리고 예전에는 이러한 계산이 16 비트 PDP에서 수행되었습니다). 비슷하게 32 비트 폴라를 사용하여 기후를 시뮬레이션하는 것은 계산의 혼란으로 인해 충분히 정확하지 않습니다.
slebetman

2
FWIW, 원하는 크기의 FP 단위가없는 컴퓨터에서 부동 소수점 연산을 구현하는 일반적인 방법은 정수 명령어를 사용하여 소프트웨어에서 수행하는 것입니다. 하루의 끝에서 부동 소수점 숫자의 지수와 가수는 모두 정수일뿐입니다. 우리가 그들에게 특별한 의미를 부여하는 것을 해석하는 방법입니다.
slebetman

2
x86의 @PTwr에는 실제로 데이터에 사용할 수있는 7 개의 GPR이 있으며 EBP가 포함되어 있습니다. 단지 대부분의 언어 구현의 ABI가 스택 프레임 포인터를 위해이 레지스터를 예약한다는 것입니다. 그러나 예를 들어 GCC를 사용 -fomit-frame-pointer하면 해당 레지스터를 다시 가져올 수 있습니다 .
Ruslan

13

32 비트, 64 비트 및 128 비트는 모두 "기본 데이터 유형"으로 간주 될 수있는 프로세서 의 워드 길이 를 나타냅니다. 종종 이것은 시스템의 RAM으로 /로부터 전송되는 비트 수와 포인터의 너비입니다 (단 하나의 포인터가 액세스 할 수있는 것보다 더 많은 RAM에 액세스하기 위해 소프트웨어를 사용하는 것을 막을 수는 없지만).

일정한 클럭 속도 (아키텍처의 다른 모든 것이 일정 함)를 가정하고 메모리 읽기 / 쓰기가 동일한 속도라고 가정하면 (여기서는 1 클럭 사이클을 가정하지만 실제로는 그렇지 않습니다) 64 비트 컴퓨터에서 단일 클록 주기로 2 개의 64 비트 숫자를 추가합니다 (RAM에서 숫자를 가져 오는 경우 세 개).

ADDA [NUM1], [NUM2]
STAA [RESULT]

32 비트 시스템 에서도 동일한 계산을 수행 할 수 있습니다 . 그러나 32 비트 시스템에서는 하위 32 비트를 먼저 추가하고 오버 플로우를 보상 한 다음 추가해야하므로 소프트웨어에서이를 수행해야합니다. 상위 64 비트 :

     ADDA [NUM1_LOWER], [NUM2_LOWER]
     STAA [RESULT_LOWER]
     CLRA          ; I'm assuming the condition flags are not modified by this.
     BRNO CMPS     ; Branch to CMPS if there was no overflow.
     ADDA #1       ; If there was overflow, compensate the value of A.
CMPS ADDA [NUM1_UPPER], [NUM2_UPPER]
     STAA [RESULT_UPPER]

내가 만든 어셈블리 구문을 통해 더 짧은 워드 길이 머신에서 고정밀 연산이 어떻게 기하 급수적으로 더 오래 걸릴 수 있는지 쉽게 알 수 있습니다. 이것이 64 비트 및 128 비트 프로세서의 핵심 요소입니다. 단일 작업에서 더 많은 수의 비트를 처리 할 수 ​​있습니다. 일부 기계에는 캐리 (예 : ADCx86) 와 함께 다른 수량을 추가하기위한 지침이 포함되어 있지만 위의 예는 임의의 정밀도 값을 염두에두고 있습니다.


이제 이것을 질문으로 확장하기 위해 사용 가능한 레지스터보다 큰 숫자를 추가하는 방법을 간단하게 알 수 있습니다. 문제를 레지스터 크기의 덩어리로 나누고 거기서부터 작업합니다. @MatteoItalia 에서 언급했듯이 x87 FPU 스택은 80 비트 수량을 기본적으로 지원하지만이 지원이없는 시스템 (또는 부동 소수점 단위가 완전히없는 프로세서)에서는 동등한 계산 / 작동 이 소프트웨어에서 수행되어야합니다 .

따라서 80 비트 숫자의 경우 각 32 비트 세그먼트를 추가 한 후 81 번째 비트로 오버플로를 확인하고 선택적으로 상위 비트를 0으로 만듭니다. 소스 및 대상 피연산자 크기가 지정되어있는 특정 x86 및 x86-64 명령어에 대해 이러한 검사 / 0이 자동으로 수행됩니다 (1 바이트 폭부터 2의 거듭 제곱에만 지정되지만).

물론 부동 소수점 숫자의 경우 가수와 유효 숫자가 오프셋 형식으로 묶여 있기 때문에 이진 덧셈을 수행 할 수 없습니다. x86 프로세서의 ALU에는 IEEE 32 비트 및 64 비트 플로트에이를 수행하기위한 하드웨어 회로가 있습니다. 그러나 FPU (부동 소수점 단위)가없는 경우에도 소프트웨어에서 동일한 계산을 수행 할 수 있습니다 (예 : GNU Scientific Library 를 사용하여 아키텍처에서 컴파일 할 때 FPU를 사용하여 소프트웨어 알고리즘으로 폴 백함). 부동 소수점 하드웨어를 사용할 수없는 경우 (예 : FPU가없는 임베디드 마이크로 컨트롤러의 경우).

충분한 메모리가 주어지면, 더 많은 정밀도가 필요할수록 더 많은 메모리를 사용하여 임의의 (또는 실제 범위 내에서 "무한"정밀도) 정밀도로 계산을 수행 할 수 있습니다 . 이것의 한가지 구현은 GNU Multiple Precision 라이브러리에 존재하며, 정수, 합리적, 부동 소수점 연산에서 (정확히 RAM이 가득 찰 때까지) 무제한 정밀도를 허용합니다.


2
가장 중요한 세부 사항은 언급하지 못했습니다. x86 플랫폼의 x87 FPU에는 80 비트 너비의 부동 소수점 레지스터가 있으므로 기본 계산은 실제로 80 비트 부동 소수점에서 수행되므로 소프트웨어에서 아무것도 에뮬레이션 할 필요가 없습니다.
Matteo Italia

@MatteoItalia 나는 지금 그것을 참조하십시오, 감사합니다. 원래 질문은 x86에서 확장 된 80 비트 부동 소수점의 특정 구현이 아니라 프로세서 워드 크기보다 큰 숫자에서 연산을 수행하는 방법에 대한보다 일반적인 개요를 요구한다고 생각했습니다. 80 ...). 나는 이것을 더 잘 반영하기 위해 지금 답변을 업데이트했습니다. 헤드 업 주셔서 감사합니다.
획기적인

5

시스템의 메모리 아키텍처는 한 번에 32 비트 만 이동할 수 있지만 더 큰 숫자를 사용하는 것을 막지는 않습니다.

곱셈을 생각하십시오. 곱셈 테이블을 최대 10x10까지 알 수 있지만 한 장의 종이에서 123x321을 수행하는 데 아무런 문제가 없습니다. 테이블을 여러 작은 문제로 나누고 개별 숫자를 곱하고 캐리 등을 돌보는 것입니다.

프로세서도 같은 작업을 수행 할 수 있습니다. "오래된 시대"에는 부동 소수점 연산을 수행 할 수있는 8 비트 프로세서가있었습니다. 그러나 그들은 어리 석었습니다.


1
그들은 특정 시점 이후에 느렸다. 특정 사양으로 자신을 제한하면 "빠른"부동 소수점 연산을 작성할 수 있습니다.
Ramhound

3

"32 비트"는 실제로 일련의 판결이 아니라 프로세서를 분류하는 방법입니다. "32 비트"프로세서에는 일반적으로 32 비트 범용 레지스터가 있습니다.

그러나 프로세서의 모든 내용을 32 비트로 수행해야하는 요구 사항은 없습니다. 예를 들어 "32 비트"컴퓨터에 28 비트 주소 버스가있는 것은 들어 보지 못했습니다. 하드웨어를 만드는 것이 더 저렴했기 때문입니다. 64 비트 컴퓨터에는 종종 같은 이유로 40 비트 또는 48 비트 메모리 버스 만 있습니다.

부동 소수점 산술은 크기가 다른 또 다른 장소입니다. 많은 32 비트 프로세서가 64 비트 부동 소수점 숫자를 지원했습니다. 부동 소수점 값을 범용 레지스터보다 넓은 특수 레지스터에 저장하여이를 수행했습니다. 이러한 큰 부동 소수점 숫자 중 하나를 특수 레지스터에 저장하려면 먼저 두 개의 범용 레지스터에서 숫자를 분할 한 다음 특수 레지스터에서 부동 소수점으로 결합하는 명령을 발행합니다. 일단 부동 소수점 레지스터에서 값은 한 쌍의 32 비트 반이 아닌 64 비트 부동 소수점으로 조작됩니다.

언급 한 80 비트 산술은 특별한 경우입니다. 부동 소수점 숫자로 작업 한 경우 부동 소수점 반올림 문제에서 발생하는 부정확성에 익숙합니다. 반올림에 대한 한 가지 해결책은 더 많은 정밀도를 갖는 것이지만 더 큰 수를 저장해야하며 개발자가 메모리에 비정상적으로 큰 부동 소수점 값을 사용하도록해야합니다.

인텔 솔루션은 부동 소수점 레지스터가 모두 80 비트이지만 레지스터에서 값을 이동하는 명령은 64 비트 숫자로 기본적으로 작동합니다. Intel의 x87 부동 소수점 스택 내에서 완전히 작동하는 한 모든 작업은 80 비트 정밀도로 수행됩니다. 코드가 부동 소수점 레지스터에서 해당 값 중 하나를 가져와 어딘가에 저장해야하는 경우 64 비트로 잘립니다.

이야기의 교훈 : "32 비트"와 같은 분류는 더 깊이 들어가면 항상 더 위험합니다!


그러나 32 비트 부동 소수점 값을 16 비트 시스템 (또는 32 비트 시스템에 64 비트 부동 소수점 값)을 사용하면 더 많은 메모리 만 필요합니다 (레지스터는 두 번 레지스터해야합니까)? 또는 정보를 처리하면 오버 헤드가 발생하므로 시간이 더 걸리나요?
markzzz

@markzzz : 다수의 레지스터 작업은 거의 항상 더 많은 시간이 걸립니다
Mooing Duck

32 비트 부동 소수점 값을 특수 레지스터에로드하는 데 시간이 더 걸립니다. 그러나 일단 특수 목적 부동 소수점 레지스터에 32 비트 부동 소수점으로 저장되면 하드웨어는 해당 부동 소수점 값에서 최고 속도로 작동합니다. "16 비트"는 GENERAL 목적 레지스터의 크기만을 나타냅니다. 부동 소수점 레지스터는 작업에 맞게 특별히 크기가 조정되며 더 넓을 수 있습니다 (귀하의 경우 32 비트 폭)
Cort Ammon

2

"32 비트"CPU는 대부분의 데이터 레지스터가 32 비트 레지스터이고 대부분의 명령어는 해당 32 비트 레지스터의 데이터에서 작동합니다. 32 비트 CPU는 한 번에 메모리 32 비트와 데이터를주고받을 수도 있습니다. 32 비트 인 대부분의 레지스터가 모든 레지스터가 32 비트 인 것은 아닙니다. 짧은 대답은 32 비트 CPU가 80 비트 부동 소수점 레지스터 및 해당 명령어와 같은 다른 비트 수를 사용하는 일부 기능을 가질 수 있다는 것입니다.

@spudone이 @ultrasawblade의 답변에 대한 의견에서 언급했듯이, 부동 소수점 연산을 통합 한 최초의 x86 CPU는 Intel i486 (특히 80486DX는 아니지만 80486SX는 아님)으로, i486 마이크로 프로세서 프로그래머의 15-1 페이지 에 따르면 Reference Manual 은 숫자 레지스터에 개별적으로 주소를 지정할 수있는 80 비트 숫자 레지스터 8 개를 포함합니다. i486에는 32 비트 메모리 버스가 있으므로 80 비트 값을 전송하면 3 번의 메모리 작업이 필요합니다.

486 세대의 전임자 인 i386에는 통합 부동 소수점 연산이 없었습니다. 대신, 외부 부동 소수점 "코 프로세서"(80387) 사용을 지원했습니다.이 코 프로세서는 80387 프로그래머 참조 서의 2-1 페이지에서 볼 수 있듯이 i486에 통합 된 기능과 거의 동일한 기능을 가졌습니다 .

80 비트 부동 소수점 형식은 8086 및 8088의 수학 보조 프로세서 인 8087에서 시작된 것으로 보입니다. 8086 및 8088은 16 비트 CPU (16 비트 및 8 비트 메모리 버스 포함)였으며 여전히 가능했습니다. 보조 프로세서에서 80 비트 레지스터를 이용하여 80 비트 부동 소수점 형식을 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.