일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- this call
- return by reference
- diamond inheritance
- new&delete
- virtual inheritance
- c++ basic practice
- delete function
- pointer to member data
- vector capacity
- increment operator
- discord bot
- c++ multi chatting room
- operator overloading
- placement new
- conversion constructor
- std::ostream
- std::cout
- std::vector
- virtual function table
- virtual destructor
- 더 지니어스 양면포커
- vector size
- C++
- member function pointer
- std::endl
- base from member
- virtual function
- constructor
- dynamic_cast
- suffix return type
- Today
- Total
I'm FanJae.
[System Programming] 컴퓨터 구조의 접근방법 본문
1. 컴퓨터 구조의 접근 방법
1-1. 컴퓨터를 디자인 하자
- 여기서 디자인할 요소는 CPU를 의미한다.
- 실제로 존재하는 컴퓨터를 디자인 하는게 아닌 가상의 컴퓨터를 디자인 한다고 생각해보자.
- 일반적으로 컴퓨터(CPU) 디자인은 레지스터와 명령어에 대한 디자인이다.
- CPU를 디자인 하기 위해서는 H/W Logic 전문가, Algorithm 전문가, Interface 전문가, 컴퓨터 구조의 특성을 고려할 수 있는 프로그램 전문가 등이 참여한다.
명령어 : 프로그래밍 언어로 프로그래밍한 것을 컴파일 했을때 번역되어 나오는 명령어들의 집합
명령어의 구성에 따라서 레지스터 셋이 결정되서 레지스터 셋이 나와야 H/W 구성이 나올 수 있다.
1-2. 레지스터 디자인의 핵심
① 레지스터를 몇 비트로 구성할 것인가?
- 레지스터의 수는 시스템 비트 수와 일치한다. N비트 시스템이면 레지스터도 N비트이다.
- 명령어의 길이가 n비트이기 때문에, 레지스터도 n비트여야 하나의 명령어를 저장 가능하다.
※ 본 예시에서는 16비트로 한다. (32비트, 64비트 시스템으로 하면 다소 복잡해진다.)
② 몇 개 정도로 레지스터를 구성할 것인가?
※ 본 예시에서는 8개로 구성한다.
③ 레지스터 각각을 무슨 용도로 사용할 것인가?
- 레지스터는 특별한 목적을 가지고 있는 메모리 장소이다.
- 즉, 목적과 용도를 정한다. 그렇게 하면 명령어가 단순해지고, 속도가 빨라진다.
- r0 ~ r3 까지의 레지스터는 연산을 필요한 레지스터이다.
- r4 ~ r7은 특별한 용도를 가진 레지스터로 지정했다.
1-3. 명령어 구조 및 명령어 디자인
- 레지스터를 디자인을 완료했으므로, 이를 근거로 명령어를 디자인해야 한다.
- 명령어의 기본 모델 : 레지스터를 16비트로 설정했으므로 명령어도 16비트로 지정된다.
- 명령어의 구성 : 명령을 수행하기 위한 모든 정보가 들어있어야 한다.
- 사칙연산을 진행하기 위해서는 아래와 같은 정보가 필요하다.
① 연산자
② 피연산자
③ 연산결과를 저장하기 위한 피연산자
④ 예약 정보 (추후 재언급)
- 위 그림에서 ADD 연산자 뒤를 잇는 세 개의 비트에는 연산결과를 저장할 저장소 정보를 둔다.
- 항상 연산결과를 저장할 레지스터 정보만 올 수 있도록 제한한다.
※ 따라서, 레지스터가 총 8개이므로, 3비트로 할당하였다.
- 그 뒤의 4개 비트와 또 그 뒤를 잇는 네개의 비트에는 레지스터 정보나 숫자가 오게 디자인 되었다.
- 레지스터가 정보가 오면 레지서트 안에 저장된 데이터를 참조한다는 의미로 해석하면 된다.
- 사칙연산에 대한 심볼과 코드
연산의 의미 | 심볼 | 2진 코드 |
덧셈 | ADD | 001 |
뺄셈 | SUB | 010 |
곱셈 | MUL | 011 |
나눗셈 | DIV | 100 |
- 레지스터에 대한 심볼과 코드
레지스터 심볼 | 2진 코드 |
r0 | 000 |
r1 | 001 |
r2 | 010 |
r3 | 011 |
r4, ir | 100 |
r5, sp | 101 |
r6, lr | 110 |
r7, pc | 111 |
- 연산의 대상이 되는 피연산자는 숫자가 될 수도 있고, 레지스터가 될 수도 있다.
- 피연산자가 오는 부분에서 숫자인가 레지스터인가 구분이 필요하다.
- 즉, 이에 따라서 첫번째 비트는 숫자인가 레지스터인가를 판별하는 값으로 사용해야 한다.
※ 여기서는 피연산자를 표현하는 부분에서 맨 앞비트가 1이면 레지스터로 전제하였다.
- 어셈블리 언어 기반의 프로그램을 구현하면 아래와 같다.
ADD r2, r1, 7
- 어셈블러에 의한 바이너리 코드 생성
0000101010010111
- 이 명령어가 컨트롤 유닛으로 전달되어 그 의미가 해석되면, 컨트롤 유닛은 CPU의 각 모듈에 명령을 내린다.
- 이때 Fetch되는 명령어는 ir(Instruction Register)에 저장된다.
※ 즉, ir은 다음 번에 실행하게 될 명령어를 미리 가져다 놓는 용도로 사용된다.
- 연산 결과(저장소)는 반드시 레지스터 이름이 와야 한다.
- 레지스터에만 저장하도록 제한하는 이유는 메인 메모리에 그 결과를 저장하지 않는 이유는 데이터를 메모리에서 옮기고 메모리로 보내는 과정 때문에 명령어 구조가 복잡해지고, 하드웨어 구성도 복잡해지기 때문이다.
- 명령어 종류에 따라 처리되는 시간이 달라질 수 있다.
1-4. RISC vs CISC
① RISC
- 단순하고 고정된 명령어로 빠른 처리를 목표로 하는 구조이다.
1) 장점
- RISC는 명령어가 단순하고 고정된 형식으로 명령어 해석과 실행이 빠르다.
- 대부분의 연산이 레지스터 간에서 이루어져서 메모리 접근이 적다.
- 명령어가 고정된 크기와 형태를 가지므로 파이프라인(Pipelining) 구조를 구현하기에 적합하며, 여러 명령어를 동시에 처리할 수 있어 CPU 성능을 크게 향상시킨다.
2) 단점
- 복잡한 작업 수행시 단순한 명령어를 연속으로 실행해야 해서 명령어 수가 많아질 수 있다.
- 명령어가 단순하므로 복잡한 작업을 수행하므로 SW적으로 많은 노력이 필요하다. (Ex. RISC는 스택 관련 명령어가 존재하지 않는다. )
② CISC
- 복잡한 명령어로 다양한 작업을 적은 수의 명령어로 처리하는 구조이다.
1) 장점
- 복잡한 명령어 구조에 따른 하나의 명령어로 여러 작업 수행이 가능하고, 프로그램의 길이를 줄이거나 메모리 공간을 절약 가능하다.
- CISC는 명령어 하나로 메모리 접근 및 연산을 동시에 수행 가능하여, 연산의 유연성이 높다.
2) 단점
- 명령어가 복잡하고 다양한 크기를 가져서, 해석하는데 시간이 많이 걸리고 CPU 설계가 복잡하다.
- 명령어가 고정되어 있지 않아서 파이프라인 처리도 어렵다.
- 명령어가 복잡하다 보니 한 명령어의 실행 시간이 길다.
'System Programming' 카테고리의 다른 글
[System Programming] 프로그램 구현 관점에서 64비트 기반 프로그래밍 / 오류의 확인 (0) | 2024.09.11 |
---|---|
[SYSTEM PROGRAMMING] WIN32와 WIN64 (0) | 2024.09.09 |
[SYSTEM PROGRAMMING] MBCS와 WBCS 동시 지원 (0) | 2024.09.03 |
[System Programming] Windows 에서의 유니코드 (1) | 2024.08.30 |
[System Programming] 프로그램의 실행과정 / 하드웨어 구성의 재접근 (0) | 2024.08.26 |