Floating Point Number Encoding(IEEE 754 Standard)
Floating Point
실수는 아주 큰 숫자 또는 아주 작은 숫자도 포함한다.
-2.34 * 10^56(normalized)
+0.002 * 10^-4(not normalized)
+987.02 * 10^9(not normalized)
위와 같은 표현을 scientific notation이라고 한다. 소수점 앞에 한자리수만 존재하고 0이 아니면 그걸 normalized 그렇지 못하면 not normalized라고 한다.
이진법에서는 +-1.xxxxxx * 2^yyyyy와 같이 표시된다. 중요한건 우리는 xxxxx와 yyyy정도 그리고 sign만 restore하면 된다 그러면 이 숫자를 읽어올 수 있다.
Floating Point Standard
Defined by IEEE Std 754-1985, 예전에는 각 회사마다 standard가 있어서 호환성 문제가 있었다. 요즘에는 다 IEEE std를 사용하여 통일시켰다. 이 standard는 defined two kinds of precision level. Single precision(32비트)(예.float in c), double precision(64비트) (예.double in c)
IEEE Floating-Point Format
실수를 저장하기 위해서 3가지가 필요한데 첫번째는 sign이다. Exponent는 xxxxx를 뜻하는 부분이다. Fraction은 yyyy부분이다 fraction의 다른 이름은 mantisa이다.
Single precision mode에서는 exponent는 8비트 fraction은 23비트이다.
Double precision mode에서는 exponent는 11비트 fraction은 52비트이다.
위의 값들을 잘 알고 있다면 이 값을 쉽게 알 수 있다.
X= (-1)^s * (1+Fraction) * 2^(Exponent-Bias)
Fraction에 1을 더한 이유는 우리가 소수점 이하부분만 기록하였기 때문에 잊고있었던 정수부분을 추가해준 것이다.
Bias는 뭐일까. Bias는 exponent의 크기에 의해 정해진다. Exponent가 8비트이면 bias는 2^7 -1이다. 이는 exponent의 값의 범위이기도 하다. 우리가 exponent을 저장할 때 실제로는 bias값과 exponent의 합을 저장하게 된다. bias더하면 실제의 음수를 저장하지 않고서도 음수라는 것을 표현할 수 있다. 어쩔때 exponent를 excess representation이라고 하기도 한다.
Single Precision Range
일단 exponents 00000000와 11111111은 제한이 되어 있다. 그래서 활용가능한 부분은 0000001~11111110까지이다.
가장 작은 값은 exponent가 00000001일때이고 actual exponent는 -126이다. 그럼 exponent의 필드는 2^-126이 된다. Fraction은 모두 0이다 fraction에서는 1이 생략되었으니 significand는 1.0이다. 결국 가장 작은 값은 1.000 * 2^126 (1.2*10^38)이 된다
가장 큰 값은 exponent가 11111110일 때이다. 가장 큰 exponent는 254-127=127이 된다. Exponent의 필드는 2^127이다. Fraction은 1111..11이다. 표현할 수 있는 가장 큰 값은 2.0*2^127이 된다. 이는 3.4*10^28이다.
Double-Precision Range
Single precision과 비슷하다.
Smallest valued의 actual exponent은 -1022이여서 1.0*2^1022 (2.2*10^-308)가 된다.
Largest value의 actual exponent은 1023, 2.0 * 2^1023(1.8*10^308)이 된다.
Floating-Point Precision
실수넘버의 precision이라고 하면 결국 중요한 비트를 의미한다. 실수변수는 relative precision을 가지고 있다. 얼마나 크든 얼마나 작든 number of effective digits는 같다.
실수에서 significant base 23 bits. 우리 모두 1 point zero omit one in front of msb of the significand bit. MSB of the significand field has the weight of 2^-1. 23비트의 LSB는 2^23 weight을 가지게 된다. 그래서 number of effective digit in binary는 23. 이를 decimal로 바꾸면 6 decimal digits이다.
더블에서는 16 decimal digits of precision. 이게 normalized form이다. Order of actual value는 exponent fiel에 의해 결정이 된다. 그래서 숫자가 얼마나 크던 똑 같은 precision을 같게 된다.
Floating-Point Example
Represent -0.75
-0.75=(-1)^1 * 1.1 * 2^-1
Normalized form이고 s는 1이다. Fraction = 1000..00 exponent = -1 + Bias
Single: 101111110000…00
Double: 10111111111101000…00
Convert binary floating point value to decimal
1 10000001 01000..00
S=1
Fraction = 01000..00
Exponent = 10000001 = 129
X=(-1)^1 * (1+01)*2^(129-127)
=(-1)*1.25*2^2
-5.0
Denormal Numbers
Exponent가 모두 0일 때 새로운 방식으로 interprete하게 된다. 이때는 fraction에 1을 더하지 않고 1-bias(-126)가 된다
Smallest value than normal numbers 이 숫자는 1.00000 * 2^126이다. 가장 큰 수는 0.11111 * 2^-126이다. 점차 숫자가 작아지는 것을 볼 수 있다. 이는 0과 근사해진다고 할 수 있다. 가장 작은 denormalized value는 +-0.0.
Infinities and NaNs
Exponent가 모두 1일이고 fraction이 모두 0일 때 값은 +,-무한대라고 한다. 한번 값이 무한대로 결정이 되면 계속해서 무한대가 된다. 무한대에 어떤 값을 더하거나 빼도 무한대이기 때문
Exponent가 모두 1이고 fraction이 모두 0이 아니면 Not-a-Number(NaN)이 된다. 이를 printf하면 NaN이 출력된다.
A Summary of IEEE 754 FP Standard Encoding
Floating Point Arithmetic
Floating-Point Addition
우리가 9.999*10^1 + 1.610 * 10^-1을 계산한다고 할 때 먼저 봐야할 것은 10의 power이다. 여기서 10의 power가 다르기 때문에 같은 power를 갖도록한다.
1. Align decimal points 9.999 * 10^1 + 0.016*10^1
2. Add significands 9.999 * 10^1 + 0.016*10^1 = 10.015 * 10^1
3. Normalize result and check for over/underflow 1.0015 * 10^2
4. Round and renormalized if necessary 1.002*10^2 effective digit을 4개라고 고려
잘 이 단계를 살펴본다면 rounding은 normalized form을 break할 수도 있다. 예를 들어 9.002가 되면 rounding을 하여 10.002가 된다. 이건 normalized form이 아니기 때문에 다시 normalized해야 한다. 그래서 effective number가 바뀔 수도 있다. 그래서 step3과 4가 계속 반복될 수도 있다. 이 과정에서 effective form이 많이 차이가 나지 않도록 조정해야한다.
이번에는 4-digit binary예시이다.
1.000*2^01+-1.110*2^-2(0.5+ -0.4375)를 계산한다고 하자
1. 1.000 * 2^-1 + -0.111 * 2^-1
2. 1.000 * 2^-1 + 0.111 * 2^-1 = 0.001 * 2^-1
3. 1.000 * 2^-4 no overflow
4. 1.000 * 2^-4 = 0.0625
FP Adder Hardware
실수 adder는 정수 adder보다 더욱 복잡하다. 한 사이클에 끝낼려면 엄청 오래걸린다. 왜냐하면 복잡한 회로는 긴 clock cycle이 필요하기 때문이다. 그래서 in modern cpu, fp adder usually takes multiple stages/cycles. Intel에서 fp add를 실행하면 6clock cycle정도 걸린다. Pipelining을 하면서 fp adder작업을 빨리하게 되었다.
Step1은 1~2clock에 끝난다. Step2,step3,step4각각 1clock이 걸린다.
Floating-Point Multiplication
1.110 * 10^10 * 9.200 * 10^-5
1. Add exponents 10+ -5 = 5
2. Multiply significands 1.110 * 9.200 = 10.212 -> 10.212 * 10^5
3. Normalize result & check for over/underflow 1.0212 * 10^6
4. Round and renormalize if necessary 1.021 * 10^6
5. Determine sign of result from signs of operands +-1.021 * 10^6
Binary example
1.000*2^-1 * -1.110 * 2^-2(0.5*-0.4375)
1. unbiased: -1 + -2 = -3 biased: (-1+127) + (-2 +127) = -3 + 127
2. 1.000*1.110 = 1.1102 -> 1.110*2^-3
3. 1.110*2^-3
4. same
5. -1.110 * 2^-3 = -0.21875
FP Arithmetic Hardware
FP adder와 복잡도가 비슷함. FP arithmetic hardware는 덧셈, 뺄셈, 곱하기, 나누기 같이 사용할 수도 있다. FP arithmetic hardware가 fp를 integer conversion할 수 있게 지원해준다.
이러한 기능들은 여러 cycle이 필요하다. 하지만 pipelining으로 속도를 빠르게 해줄 수 있다. 여러개의 반복적인 기능을 요구하면 속도를 빨라지게 할 수 있지만 다양한 기능을 사용했을 때는 효율적이지 않을 수도 있다.
FP Instructions in MIPS
Fp unit is Implemented in coprocessor1. Coprocessor1이 MIPS에서 실수 instruction을 지원해준다. 처음에 MIPS에서 cpu밖에 없어서 fp instruction지원을 해주지 않았다.
FP 레지스터들은 coprocessor에 따로 지정되어 있다. 32 single-precision: $f0~$f31. 각 레지스터 32비트만큼 길고 각 레지스터는 하나의 single precision point number를 저장할 수 있다.
더블 precision은 어떻게 저장될까. paired된다. $f0/$f1이 페어할 수 있고 $f2/$f3가 페어가 될 수 있다. 페어는 하나의 double precision floating point number를 저장 할 수 있다. MIPS ISA는 32 * 64비트 FP 레지스터를 지원한다. 이때는 페어가 필요없다.
Fp instructions operate only on FP registers
Fp load and store instructions
Lwc1, ldc1, swc1, sdc1 #w가 있으면 single precision, c1
-ldc1 $f8, 32($sp) #레지스터 name은 반드시 fp 레지스터여야 한다.
Single-precision arithmetic
Add.s, sub.s, mul.s, div.s
Double-precision arithmetic double operation에는 페어의 첫번째 레지스터가 페어를 대표하게 된다.
Add.d, sub.d, mul.d, div.d
Single-and double-precision comparision
c.xx.s, c.xx.d(xx is eq, neq, lt, le, gt, ge) coprocessor에 있는 특별한 flag이다.
Sets or clears FP condition-code bit
Bracn on FP condition code true or false
Bc1t, bc1t
Ex) Bc1t TargetLabel #Flag가 clear일 때 점프를 한다.
Accurate Arithmetic(rounding방법에 대해서…)
1,001이 있을 때 3의 efficinet만 필요하면 1을 rounding 해주어야한다. 1은 rounding에서 extra digit이다. IEEE에서 arithmetic hardware must have extra bit to use in rounding shcheme. 처음 extra비트는 guard비트 그다음은 round비트 그 다음은 sticky비트라고 한다.
0.1가 있을 때 오른쪽으로 shift하면 0.01이다. 우리가 소수점 두개만 저장가능하다고 하자. 그리고 다시 오른쪽으로 shift하면 1은 저장가능한 공간에서 빠져나가게 된다. 이때 우리는 round를 해주어야 하고 1은 guard비트이다. 다시 right shift를 한번에 두번 할 때 guard bit는 1, round 비트는 1이다. 라운딩 스킴은 guard비트를 먼저 볼 것이다. 0이면 round scheme은 round down을 시킨다. 1이면 0.0010은 0.01와 0.00사이에 있는 것이다. 이런 상황(0.0010)을 tie case 라고 한다. 근데 round비트가 1이면 tie case가 아니다. 왜냐하면 0.0011은 0.01에 조금 더 가까이 있어서 round up이 된다. sticky비트는 extension of round비트라고 생각하면 된다. 0.00101이 있을 때 0.01에 가까운데 sticky비트는 round비트 다음에 하나의 digit라고 1이 있으면 sticky비트는 1이다. 0.0010000…숫자에서는 guard가 1이고 round가 1이면 round up이 되고 round가 0이면 sticky에 의해서 round up/down을 판단한다.
모든 CPU가 위의 옵션을 지원하는 것은 아니다. 왜? Trade-off between hardware complexity, performance and market requirements…
Associativity
컴파일러가 arithmetic operator를 optimize하면서 operator의 순서를 바꾸기도 하는데 FP operands는 건드리지 않는다. 왜냐하면 associativity가 없기 때문이다. Associativity가 없다는게 무슨소리인가? (x+y)+z와 x+(y+z)가 항상 같지 않다는 것이다.
X,y가 굉장히 큰 수이고 z가 아주 작은 숫자일 때 z는 거의 무시(생략)될 때가 있다.
(설명사진은 추후 추가 예정)
'시스템프로그램' 카테고리의 다른 글
[컴퓨터구조개론] 4. Integer Arithmetic (2) | 2020.10.19 |
---|---|
[컴퓨터구조개론] 3. MIPs Instruction and Set Architecture(2) (0) | 2020.10.18 |
[컴퓨터구조개론] 2.MIPS Instruction and Set Architecture(1) (0) | 2020.10.17 |
[컴퓨터구조개론] 1. Computer abstraction and technology (0) | 2020.10.17 |
[시스템프로그램]03-1-1 Program encodings(1) (0) | 2020.05.02 |
댓글