봉황대 in CS

[Chapter 3. 컴퓨터 연산] 연산에 있어서 겪을 수 있는 오류와 함정들 본문

Computer Science & Engineering/Computer Architecture

[Chapter 3. 컴퓨터 연산] 연산에 있어서 겪을 수 있는 오류와 함정들

등 긁는 봉황대 2022. 8. 30. 15:50

* 본 글은 '컴퓨터 구조 및 설계: 하드웨어/소프트웨어 인터페이스(Computer Organization and Design: The Hardware/Software Interface) 5th edition'의 내용과 2021학년도 1학기에 수강한 '컴퓨터 구조' 과목 강의 내용을 함께 정리하여 작성하였습니다.

 

 

본서에서는 '오류'와 '함정'이라는 단어를 사용하는데, 각각의 의미는 다음과 같다.

 

오류(Fallacy) : 많은 사람들이 공통적으로 잘못 알고 있는 부분

함정(Pitfall) : 흔히들 저지르기 쉬운 실수

 


[ 오류 ]

한 비트 왼쪽 자리이동 명령어가 2를 곱해준 것과 같은 결과를 보이듯이

오른쪽 자리이동 명령어는 2로 나누어 준 것과 같은 결과를 나타낸다.

 

 

부호 없는 정수(unsigned integer)에서는 그러하지만,

부호 있는 정수(signed integer)를 사용하는 경우에서는 아니다.

 

 

예를 들어, -5를 4로 나눈다고 해보자.

몫은 -1이어야 한다.

 

-5의 2의 보수법 표현은 다음과 같다.

1111 1111 1111 1111 1111 1111 1111 1011

 

이러한 오류에 따르면, 2비트 오른쪽으로 자리이동(right shift 2) 한 것은 4로 나눈 것과 같아야 한다.

0011 1111 1111 1111 1111 1111 1111 1110

 

하지만 부호 비트가 0이 되는 것에서부터 잘못되었다는 느낌이 싸악 든다.

이 수는 -1이 아닌, 양수의 굉장히 큰 수 1,073,741,822가 되어버렸다.

 

 

해결책은 좌측에 0을 채우는 것이 아닌, 1을 채우는 것이다.

1111 1111 1111 1111 1111 1111 1111 1110

 

하지만 이것도 값이 정확하지 않다. 결과가 -1이 아닌 -2가 되었기 때문이다.

 


[ 함정 ]

부동소수점의 덧셈은 결합 법칙이 성립하지 않는다.

 

 

2의 보수 정수 덧셈에서는 오버플로가 발생해도 결합 법칙,  c + (a+b) = (c+a) + b는 성립한다.

하지만 부동소수점 수는 실수의 근사치이고 컴퓨터 연산도 제한된 정밀도를 갖기 때문에 부동소수점 수에서는 성립하지 않는다.

 

 

이는 다음의 예를 통해 알 수 있다.

c + (a+b) = (c+a) + b에서 c = -1.5 × 10^38, a = 1.5 × 10^38, b = 1.0

* E+38은 10^38을 의미

 

 

즉, 부동소수점 수는 정밀도에 있어서 한계가 있고, 실제 결과의 근삿값을 결과로 취하기 때문에

부동소수점에서는 결합 법칙이 성립하지 않으며 연산 순서가 결과에 영향을 주게 된다.

 


[ 오류 ]

정수 데이터형에서 사용되는 병렬 수행 방식은 부동소수점 데이터형에도 똑같이 적용된다.

 

 

프로그램은 일반적으로 병렬로 수행되는 것을 작성하기 전에 순차적 수행 버전이 작성된다.

따라서 두 버전이 같은 결과를 얻는 것이 중요하며, 만약 결과가 같지 않다면 병렬 버전이 문제가 있다고 생각할 수 있다.

 

이 방식은 컴퓨터 연산이 순차적 수행에서 병렬 수행으로 바뀌어도 결과에 영향을 미치지 않음을 가정한다.

즉, 100만 개의 수를 더할 때 한 개의 프로세서를 사용한 것과 1000개의 프로세서를 사용한 것의 결과가 같을 것임을 예상하는 것이다.

 

2의 보수법을 사용하는 정수라면 정수 덧셈은 결합 법칙이 유효하기 때문에 이 가정은 항상 옳으나,

부동소수점 덧셈은 결합 법칙이 성립하지 않기 때문에 이 가정은 옳지 않게 된다.

 


[ 함정 ]

MIPS 명령어 addiu(add immediate unsigned)는 16비트의 수치 필드(immediate field)를 부호 확장하여 사용한다.

 

 

addiu는 오버플로에 대해 신경 쓰지 않을 때 상수를 부호 있는 정수에 더하는 데에 사용된다.

MIPS는 수치를 사용하는 뺄셈 명령어를 지원하지 않으므로 음수는 부호 확장되어야 한다.

 

따라서 MIPS 구조는 수치 필드를 부호 확장하여 사용한다.

 


[ 오류 ]

이론 수학자만이 부동소수점 연산의 정확성에 신경을 쓴다.

 

실제로 부동소수점 연산의 정확성에 신경을 쓰지 않아 나타난 버그가 매우 많다.

 

 

 

반응형
Comments