컴퓨터구조 - DevWoony가 복습을 위해서 전공과목을 정리하는 내용이에요!
Compiler
의미 : 특정언어로 작성된 program text를 input으로 하여 의미를 보존한채 다른 언어의 program text로 output을 생성하는 프로그램이다.
-
Compiler는 우리가 흔히 아는 C, Java 등과 같은 언어를 Translation 하여 Assembly language로 전환하고 Assembler가 이를 기계가 알아들을 수 있는 Machine languge로 전환한다.(Object 로 결과가 나온다)
-
Compiler의 복잡도는 언어의 syntax와 abstraction 정도에 따라 달라진다. C가 C++보다 단순한 컴파일구조를 가지는 것이 하나의 예이다.
-
컴파일러는 프로그램이 실행되기 전에 항상 실행된다.
Assembly and Pseudo-instructions
-
assembly라고 불리는 MIPS instructions을 machine code로 전환하는 프로그램은 assembler이다.
- 이름으로 되어있는 addresses, maps의 registers들을 숫자 및 binary machine language로 전환한다.
- 우리가 텍스트처럼 볼 수있는 instructions를 assembly 언어라고 불린다.
-
Instructionsds는 프로그래머에게는 해석이 되지만 hardware에서는 그렇지 않다.
- Load imeediate(li) 32-bit의 constants 32-bit의 숫자를 가지고 오도록 하는 명령어지만 assembler는 이를 필요하다면 lui + ori 두개의 명령어로 수행하도록 해석한다.
- Load double (ld) 는 64-bit의 숫자를 load하기 위해 숫자를 구성하는 32-bit의 한쌍을 각각 두번 load한다
-
Pseudo instructions: 이는 Assembler의 의도한 생각에 의해 작성된 instruction들이다.

Object Module이란?
-
Assembler(또는 Compiler) 프로그램을 machine instruction로 전환한다.
-
조각조각으로부터 완성된 프로그램을 완성하기 위해 Objects에게 다음과 같은 정보를 제공한다.
- Header : Object module의 내용을 묘사
- Text segment : 전환된 instructions 집합
- Static data segment : 프로그램의 실행동안 필요한 data
- Relocation info : 프로그램이 로드되는 절대위치에 대한 정보
- Symbol table : 전역 정의와 외부 참조
- Debug info : 소스코드와 관련된 정보

Separate Compilation and Assembly
-
Compliation과 Assembly를 분할하면 모든코드를 한번에 컴파일 할 필요가 없어진다. 이 분할된 Object를 Linker가 이어주게 된다.


Translation and Startup
- 특정 언어로 작성된 언어가 compile 될때는 다음과 같은 과정을 가진다.

Linker Stitches Files Together
- Linker가 3개의 Object의 파일을 1개의 실행가능한 파일로 붙이는 모습을 도식화한 그림이다.

Linking Object Modules
- 생성가능한 image를 생산한다
- 조각들의 결합
- Label(branch, jump 등의 주소)을 붙임.
- 외부참조와 위치를 붙임.
- 자주 linking 하는 과정이 compiling 과정보다 오래걸릴때가 있다.
- 모든 machine code 파일을 linking하는 과정은 memory로 읽어드리는 과정이 많기 때문이다.(Memory Access 명령어는 대체로 다른 명령어보다 오래걸림)
Loading a Program
- disk에 있는 image file을 memory로 load한다.
- 조각의 크기를 결정하는 header을 읽는다.
- 가상 주소의 크기를 생성한다.
- Text(code)를 복사하고 memory에 data를 초기화시킨다.
- Arguments를 스택에 세팅한다
- register들을 초기화한다. ($sp, $fp, $gp 등)
- start 지점으로 jump한다.
Dynamic Linking
- Libary의 Link나 Load 과정이 프로그램 도중에 실행된다.
- 자동으로 새로운 library 버전을 가져온다.
- 실행 코드가 relocatable 해야한다.
- 참조된 모든 라이브러리의 정적 링크로 인한 이미지의 팽창을 방지합니다.
- Dynamic linking은 Unix와 Windows System의 기본 설정입니다.
- Dynamic Linking Library(DLL)은 처음에는 많은 overhead를 일으키지만 추후 subsequent에서는 거이 cost가 발생하지 않는다.
- Compiler는 처음에 원하는 library를 찾을 수 있도록 코드와 데이터를 세팅한다.
- Linker는 런타임도중에 주소를 빠르게 바꿔 subsequent를 호출한다.
- library에서 return하는 값은 매번 빠르다.

Compiler Optimization
- gcc comiler options
- O or O1 : code size와 excution time을 줄인다. comilation time은 고려하지 않는다.
- O2 : code size 너무 커지지 않는 범위에서 가장 빠른 excution time을 제공한다.
- O3 : code size를 전혀 고려하지않고 excution time에 치중한다.
다음은 Bubble Sort의 예제롤 각 코드를 Compile 했을 때의 결과이다.



실제 성능 비교는 다음과 같다.


Interpreter ?
- Interpreter는 하나의 source statements가 한번에 한개만 실행되도록 읽는 프로그램이다 .
- Linking이 없고 machine code 실행이 없어 호환성이 높다.
- 빠르게 실행되지만, 전체적인 동작은 compiled 된 코드보다 느리게 동작한다.
- 직관적인 actions에 대한 error 체크나 완료 보고에 유리하다. (명령을 하나하나씩만 수행하기 때문)
- Compiler를 만드는 것보다 Interpreter을 만드는 것이 훨씬 더 쉽다.

- 장단점 비교
- Comilation
- 빠른 excution
- Single file만 필요
- syntax error, 및 전체적인 코드 흐름을 통해 생성되는 에러를 잡기 유리함
- 프로그램이 실행전에 syntax error을 잡아낼 수 있음.
- Optimize가 가능함
- Interprter
- 프로그램의 debug가 매우 쉬움
- 개발시간이 빨라짐
Java's Hybrid (Compile + Interpreter)
- Bytecodes로 compile하고 이를 interpreter가 해성한다.

- Bytecodes의 장점
- JVM을 통하면 어느 플랫폼에서든 실행가능하다.
- Source code를 그대로 interprting 하는것 보다 빠르다.
- Source code가 User에게 노출되지 않는다.
- Interpreter 플랫폼에서 추가적인 security 체크와 동적할당된 코드를 확인할 수 있다.
- Java Bytecodes와 MIPS의 비교

ARM vs MIPS

- ARM은 ALU의 결과를 negative, zero, carry, overflow를 다음 instructions에서 condition으로 사용할 수 있다.
- 그러므로 모든 명령어가 condition과 함께 설계될 수 있다.
다음은 Instruction의 비교이다.

다음은 ARM instruction set이다.

그 외에도 넓은 메모리 access를 통해 멀티미디어에 유리했던 Power PC, 인텔계열의 Intel 80x86, Pentium 4 등의 CPU 등의 특징도 각각 관심이 있으면 조사해보기를 추천한다.
그래서 MIPS 설계 철학은?
- 간단하고 정규화 가능하게
- 작을수록 빠를거야!
- 우수한 설계 타협(적당적당하게!)
- 간단한거는 빠르게!
출처: [Computer Organization And Design: The Hardware/Software Interface]