전자전기공학/컴퓨터구조

[컴퓨터구조][Arithmetic/Floating point]

Sim 2024. 9. 25. 14:39
반응형

· 목차

  - Integer Addition

  - Integer Subtraction

  - Multiplication

  - Division

  - Floating Point (부동소수점)


 

 

 

 

안녕하세요. 오늘은 컴퓨터 구조에서 그리고 특히 CPU에서 사용되는 ALU의 Arithmetic에 대해서 배워보도록 하겠습니다.

 

모두가 디지털논리회로에 대해서 배워봤다면 기본적인 Arithmetic에 대해서 아실 것이라고 생각됩니다.

 

 

오늘은 Integer Addition과 Subtraction 그리고 Multiplication과 Divistion 그리고

마지막으로 Floating-point에 대해서 배워보도록 하겠습니다.

 

 

 


 

 

 

 

 

 

 

 

Integer Addition

 

 

 

 

 

 

 

 

덧셈은 가장 기본적인 부분이기 때문에 쉽게 아실 수 있으실 것이라고 생각합니다.

 

만약에 양수와 음수를 더하게 된다면 overflow를 걱정하실 일이 거의 없으실 것 입니다.

왜냐하면 양수와 음수의 덧셈은 양수 또는 음수로서 최댓값에 쉽게 도달하지 않기 때문입니다.

 

 

덧셈과 뺄셈은 쉽게 하실 수 있기 때문에 빠르게 보고 넘어가도록 하겠습니다.

 

 

 

 

 

 

 

Integer Subtraction

 

 

 

 

 

 

여기서 7 - 6은 7 + (-6)으로 볼 수 있다는 것을 아실 것 입니다.

여기까지도 아직 쉽기 때문에 빠르게 넘어가겠습니다.

 

 

 

 

 

 

Multiplication

 

 

 

 

 

 

 

 

저희가 일반적으로 곱셈을 하는 단계를 보실 수 있습니다.

저희는 한 눈으로 가능하지만, 디지털에서는 Multiplier를 shift하면서 0인지 1인지를 가늠합니다.

또한 Multiplicand를 shift 하면서 서로 비교해주게 됩니다.

왜 그런지는 곱셈의 원리를 보시면 아실 수 있습니다.

 

 

 

만약에 0이라면 저희가 어떤 값을 곱하더라도 0이라는 결과가 나오는 것을 알 수 있죠?

그렇다면 1이 나온다면 곱해지는 4자리가 모두 그대로 나온 다는 것을 아실 수 있습니다.

 

 

 

위의 곱셈의 방식을 이용해서 곱셈을 빠르게 연산하는 여러가지 방법들이 있습니다.

보시는 것과 같이 Multiplier에는 Adder연산이 들어가 있습니다. Multiplier를 빠르게 하기 위해서

Adder의 연산속도를 개선합니다. 이 방법은 아래와 같은 방법들이 있습니다.

Tree Adder 그리고 기본적으로 디지털논리회로에서 배웠던 Look Ahead Carry Adder와 Carry Skip Adder 등이 있고,

 

 

그리고 다중 비트를 병렬로 더하는 회로에서 덧셈 단계를 줄여 계산 속도를 향상시키는 데 중요한 역할을 하는

4:2 Compressor Adder 등이 있습니다.

 

 

 

연산의 속도를 개선하고 ALU를 개선하면 CPU의 성능에 좋은 영향을 주기 때문에

개선을 하기 위한 방법 또한 많이 연구중에 있습니다.

 

 

 

저희는 하드웨어 구조를 보고 있기 때문에 Multiplier를 그림으로 표현해 보자면 아래와 같습니다.

 

 

 

 

 

 

 

이제 마지막으로 LEGv8에서 사용하는 3가지 Multiply instruction에 대해서 보고 넘어가겠습니다.

 

 

  MUL SMULH UMULH
예시 코드 MUL X0, X1, X2 SMULH X0, X1, X2 UMULH
설명 X1과 X2의 곱셈 결과를 하위 64비트만 X0에 저장됩니다. 피연산자가 음수로 추측될 경우 곱셈 결과의 상위 64비트가 저장됩니다. 피연산자가 양수로 추측될 경우 곱셈 결과의 하위 64비트가 저장됩니다.

 

 

 

 

 

 

 

 

Division

 

 

 

 

 

 

 

위는 나눗셈을 계산하는 과정을 나타낸 그림입니다.

 

여기서 간략하게 설명하자면, 저희는 한 눈에 divisor와 dividend가 뺄 수 있는지 볼 수 있습니다.

하지만 디지털에서는 그렇지 않기 때문에 divisor과 dividend가 뺄 수 있을지를 shift를 통해서 확인할 수 있습니다.

 

 

 

그리고 뺄 수 있다는 것이 확인된다면, quotient에 1을 적어주고 뺄셈을 수행하고 난 이후에

계속해서 비교해주며 뺄 수 없을 때에는 dividend에서 한 자리씩 가지고 내려와서 비교해보며

뺄 수 있을 때 뺄셈을 수행해줍니다. 그리고 모든 dividend를 비교해본 상태라면 나눗셈을 끝내게 됩니다.

 

 

 

 

위의 비교 횟수와 여러가지 연산을 살펴보게 되면 꽤 오랜 시간이 걸릴 것이라는 것을 아실 수 있을 겁니다.

만약에 피연산자가 32bit라면 32번의 비교와 뺄셈을 수행해야 하기 때문에 32clock 이상의 수행을 하기 때문에

상당히 오랜시간이 걸립니다. 이에 따라서 현재도 Divider에 대한 연구가 상당히 활발하게 이뤄지고 있습니다.

 

 

 

대표적으로 많이 사용하는 것은 Restoring Division라는 것이 있고, 또 여러가지 Algorithm을 통해서 연구되고 있습니다.

예를 들어서 SRT division 같은 것들이 있을 것 같네요.

 

 

 

마지막으로 기본적인 Divider의 하드웨어 구조를 살펴보고 넘어가도록 하겠습니다.

 

 

 

 

하드웨어 구조를 보면서 위의 연산과정을 보시면 이해가 더 수월하실 거에요.

 

 

 

마지막으로 Floating point에 대해서 살펴보고 끝내도록 하겠습니다.

 

 

 

 

 

 

 

 

 

Floating Point (부동소수점)

 

 

 

 

 

Floating Point는 컴퓨터에서 실수(소수점이 있는 숫자)를 표현하기 위한 방식입니다.

부동소수점은 마치 과학적 표기법과 비슷합니다.

 

$-2.34\;* \;10^{56}$

$+0.002\; * \; 10^{-4}$

 

 

현재 저희가 살펴볼 Floating Point는 IEEE 754 표준을 따릅니다. 이 표준은 32비트(Single precision)와

64비트(double precision)의 두 가지 주요한 포맷으로 정의할 수 있습니다.

 

 

 

 

 

위를 과학적 표기법과 같이 작성한다면 아래와 같습니다.

 

 

$X \; = \; (-1)^{S} \; * \; (1+Fraction)\; * \; 2^{Exponent-Bias}$

 

 

위에서 SSign bit을 의미합니다. non-negative라면 0, negative 1입니다.

 

여기서 $(1+Fraction)$의 결과는 항상 $1.0 \le \; |significand| \; < \; 2.0$의 값을 만족합니다.

왜냐하면 Fraction은 소수점(또는 분수)의 값을 나타내며 0 ~ 1 사이의 값을 나타내기 때문입니다.

 

 

그렇다면 위의 공식에서 Bias를 어떻게 구할 수 있을까요?

Bias는 Exponent를 표현하는 비트 수에 따라 표현할 수 있는 전체 범위의 중간 값을 기준으로 설정합니다.

 

 

예를 들어서 Single precision이라면 총 8비트이기 때문에 127이 될 것 이고,

Double precision을 사용한다면 11비트이기 때문에 1023이 됩니다.

 

 

또한 여기서 주의해야 할 것이 있는데요, 바로 Exponent의 비트가 모두 0이거나 모두 1인 경우는 특별한 케이스를

나타내기 때문에 제일 작은 값을 표현하기 위해서 8비트를 예로 들자면 00000001을 사용하고

가장 큰 값을 사용하려면 11111110를 사용해서 가장 큰 값을 표현해야 합니다.

 

 

제일 작은 값을 쓰는(00000001)의 경우에는 지수가 1-127으로 -126이 되어 가장 작은 값이고,

가장 큰 값을 쓰는(11111110)의 경우에는 지수가 254-127으로 127이 된다는 것을 알 수 있습니다.

 

위는 Single precision이지만 Double precision도 마찬가지겠죠?

 

 

 

모두 0이거나 모두 1일 경우의 특수 케이스를 정리해보자면 아래의 테이블과 같습니다.

 

 

지수(Exponent) 가수 (Mantissa 또는 Fraction) 의미
모두 0 0 +0 또는 -0 (부호 비트에 따라 달라짐)
모두 0 0이 아님 비정규화된 수 (아주 작은 수)
모두 1 0 $-\infty$ 또는 $+\infty$
(부호 비트에 따라 달라짐)
모두 1 0이 아님 NaN (정의되지 않은 연산 결과)

 

 

 

테이블에서 NaN(Not a Number)은 연산 결과가 유효하지 않거나 정의되지 않은 경우에 발생하게 되는데

예를 들어서, 0을 0으로 나누는 연산이나 제곱근을 구할 수 없는 음수를 계산할 때 발생합니다.

 

 

그렇다면 여기서 왜 이런 특별한 케이스가 필요할까요?

 

비정규화된 수는 매우 작은 값을 표현하는 데 필요합니다. 예를 들어서, 0에 매우 가까운 값을 처리할 수 있고,

계산 중에 발생하는 소수점 근처의 작은 값들도 처리할 수 있습니다.

 

Infinity는 오버플로우를 처리하는 방법으로 계산 결과가 너무 커서 표현할 수 없을 때 무한대 값을

반환함으로써 오류를 방지합니다.

 

NaN은 정의되지 않거나 유효하지 않은 연산의 결과를 명확하게 처리하기 위해 필요합니다.

 

 

 

 

이제 마지막으로 Floating point의 -7.5를 어떻게 표현할 수 있는지 살펴보고 끝내보도록 하겠습니다.

 

Sign bit은 당연히 1이 됩니다.

 

그 다음으로 7.5를 표현하기 위해서 2진수로 표현하면 $111.1_{2}$입니다.

여기서 부동소수점 형식으로 표현하려면 정규화를 해야하고, 정규화 하는 과정은 1.xxx...의 형태로 만드는 것 입니다.

 

 

왜 1.xxx...의 형태로 만드는지는 잘 아실 것 입니다. 1+Fraction의 형태로 만들어야 하기 때문입니다.

 

$111.1_{2}$에서 1.111의 형태로 만들기 위해서 소수점을 왼쪽으로 2칸 움직여야 합니다.

이전에 LSL을 설명하면서 왼쪽으로 쉬프트하면 쉬프트한 비트의 칸 수를 N이라고 한다면,

$2^{N}$을 곱해줘야 한다는 것을 기억하시고 계실 것 입니다.

 

 

결국에 왼쪽으로 2칸을 움직여주면 $1.111 \; * \; 2^{2}$가 됩니다. 이렇게 되면 위에서 봤던 꼴과 많이 비슷해집니다.

 

 

$ (-1) \; * \; (1.111)\; * \; 2^{Exponent-Bias} $

 

 

여기에서 저희는 $2^{2}$라는 곱해지는 수가 있기 때문에 $2^{2+127}$으로 129는 $100000001_{2}$가 되서 -1이 됩니다.

 

 

 

이제 Floating point에 대해서 감이 잡히실거에요. 가장 확실한 것은 익힌 감을 예제에 대입해서

생각해보시면서 연습하시는게 제일 좋을 것이라고 생각됩니다.

 

 


 

 

 

 

 

지금까지 Integer Addition, Subtraction 과 Multiplication과 Division 그리고 Floating point에 대해서 배워봤습니다.

 

 

글 읽어주셔서 감사합니다.

 

 

 

반응형