| double_to_fx(a) | double형에서 고정소수점으로 변환하는 매크로로 위의 연산과 반대로 2^16을 곱해준다. |
| fx_sine(a) | sin(a)값을 고정소수점으로 변환하는 매크로로 math.h의 sin함수를 사용하여 변환을 진행한다. |
### 3. Make Build
...
...
@@ -38,6 +55,7 @@
* Target : 빌드 대상 이름.
* Dependencies : 빌드 대상이 의존하는 Target이나 파일 목록.
* Recipe : 빌드 대상을 생성하는 명령. 무조건 ```tab```을 넣어주어야 한다.
- Macro, Variable 이용
1. SRCS : 소스 파일들의 이름을 적는다.
...
...
@@ -46,10 +64,148 @@
4. CFLAGS : 컴파일에 필요한 각종 옵션을 추가한다.
5. $@ : 현재 Target 파일명
6. $^ : 현재 모든 dependency 파일들의 명단
- test.c, fx_s4716_double.c 와 fx_s4716_double.h를 make 명령어 하나로 자동으로 빌드하게 해줌
- gcc 컴파일러를 사용하였으며 mytest 실행파일과 각 c파일의 목적파일을 자동으로 생성
* -lm : math.h 라이브러리 추가
- make clean을 통해 실행파일과 목적파일을 삭제할 수 있음
- make dep를 통해 각 파일의 헤더파일을 미리 연결해줌
- make clean 명령어를 통해 자신이 지우고 싶은 실행파일과 목적파일을 정하여 삭제할 수 있음
- make dep 명령어를 통해 각 파일의 헤더파일을 자동으로 미리 연결해줌
### 4. Run Program
-`make dep `명령어를 사용해 헤더파일을 연결해준다.
-`make` 명령어를 사용해 자동으로 프로젝트를 빌드해준다.
- 지정된 파일을 실행하고 연산을 원하는 값을 두개 넣어준다.
- 두개의 값을 이용한 모든 연산을 출력한다.
## Project #2 (Using long long type & Performance Test)
### 1. Using shift operation & long long type
- 이번 프로젝트에서는 2^n을 곱하는 것이 아닌 쉬프트연산을 사용하여 >>, <<으로 곱이나 나눗셈을 표현하였다. 이를 통해 좀 더 직관적으로 고정 소수점을 표현하였고 이에따라 연산의 결과값이 정수부가 47bit를 넘는다면 overflow가 발생할 것이고 소수부가 16bit를 넘는다면 underflow가 발생할 것임을 알 수 있다.
- 처음 위의 Project #1에서는 double형을 사용하여 연산을 진행함으로써 만약 값이 크다면 그 큰 값을 표현하기에 double형이 작아 수의 손실이 일어날 수 있다. 따라서 Project #2에서는 long long형을 사용해 연산을 함으로써 div나 mul과 값이 큰 값이 나오는 연산에서도 최대한 수의 손실을 줄일 수 있게 하였다.
### 2. Added functions
- MUL
-```
#define FX_S4716_LONGLONG_MUL1(a, b) (((a) * (b)) >> 16)
```
연산의 개수가 적어 속도는 빠르지만 앞의 곱하기 연산에서 값이 커질 경우 overflow가 발생하여 값이 손실되기 쉽다.
-```
#define FX_S4716_LONGLONG_MUL2(a, b) ((a >> 8) * (b >> 8))
```
각 값의 정수부를 미리 8 쉬프트 연산을 통해 늘림으로서 위의 MUL1 보다는 느리지만 유효범위가 늘어나서 값의 손실이 적다. 계산 값이 MUL1보단 크지 않아 overflow는 잘 발생하지 않지만 작은 값의 경우 오히려 underflow가 발생할 수 있다.
sin함수의 경우 그전 프로젝트에서는 math.h에 있는 기존 라이브러리 함수를 이용했던 반면에 이번 프로젝트에서는 테이블을 만들어 들어오는 값에 대응하는 고정소수점 값을 넣어주게 만들었다. 위의 테이블에서 90이 넘게 92로 범위를 설정한 것은 배열의 크기가 91이므로 편리하게 사용하기 위해 설정해주었다.
```
fx_s4716 fx_s4716_longlong_sin(fx_s4716 a){
long long quotient, remain, result;
remain=a%180;
if(remain>90)
remain=180-remain;
quotient=a/180;
result=(sinTable[remain])*(pow(-1,quotient));
return fx_to_longlong(result);
}
```
위의 함수에서 사인함수의 각도가 90을 넘어갈 경우에 그 각도를 다시 계산해주는 연산을 넣어주어서 90이 넘어가는 a값에 해당하는 사인값도 테이블에 매칭되서 결과값을 반환하게 만들어주었다.
### 3. Performance Test
-```
gcc -pg test.c <컴파일 필요한 파일들> -m64, -m32
```
위의 명령어를 이용해 `-m64`의 경우 64비트로 컴파일이 가능하고 `-m32`의 경우 32비트로 파일을 컴파일이 가능하다. 컴파일된 비트수에 따라 double형과 longlong형의 속도가 달라진다. `-pg`옵션을 붙여줌으로써 gprof 성능분석을 할 수 있게 한다.
-```
gprof
```
gprof명령어를 사용해 프로그램의 성능 측정을 할 수 있는데 각 함수의 속도와 호출 횟수등을 확인할 수 있다. `gmon.out`파일에 성능 측정의 내용이 들어가며 리다이렉션을 통해 파일을 기록해줄 수 있다.