일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 그래프탐색
- 거리두기확인하기
- 벽부수고이동하기
- 알고리즘
- 큐
- 이모티콘할인행사
- 프림알고리즘
- 위상정렬
- 두큐합같게만들기
- 징검다리건너기
- 다익스트라
- javascript
- 구현
- 최소스패닝트리
- 사이클게임
- 파이썬
- 프로그래머스
- [1차]캐시
- DFS
- DP
- RGB거리2
- 백준
- BFS
- 자물쇠와열쇠
- 17404
- 파괴되지않은건물
- 트리의지름
- 최단경로
- 도넛과막대그래프
- 섬연결하기
- Today
- Total
블로그 이름 뭐로 하지
[컴퓨터구조] CPU 작동 원리 본문
본 글은 개발자를 위한 컴퓨터공학1 강의를 기반으로 작성됐습니다.
CPU는 컴퓨터의 네 가지 핵심 부품 (CPU, 메모리, 보조기억장치, 입출력장치) 중 하나로, 크게 ALU, 제어장치(Control Unit), 레지스터로 이루어져 있다. 메모리에 저장된 명령어를 읽어 들이고, 해석하고, 실행하는 부품이다.
CPU의 구성
- ALU(산술논리연산장치): 계산기(계산을 위한 회로들의 모임)
- 레지스터: CPU 내부의 작은 저장 장치(보통 CPU 내에 여러개 있음)
- 제어장치: 제어 신호를 내보내고, 명령어를 해석하는 장치
- 제어 신호: 컴퓨터 부품들을 관리하고 작동시키기 위한 전기 신호 ex) CPU가 메모리에 저장된 값을 읽고 싶을 땐 메모리를 향해 메모리 읽기 라는 제어 신호를 보낸다.
CPU의 대략적인 작동 순서
- CPU의 제어장치는 메모리를 향해 메모리 읽기 라는 제어 신호를 내보낸다.
- 메모리는 1번지에 저장돼있는 명령어를 CPU에게 보낸다. 정확하게는 CPU의 레지스터에 보낸다.
- 제어장치는 명령어를 해석하기 때문에 앞에서 받아온 명령어(더하라, 3번지와 4번지를)를 해석하고, 3번지와 4번지에 있는 데이터가 필요하겠구나~ 생각하고 메모리의 3번지 4번지에 있는 데이터를 가져오기 위해 메모리 읽기 라는 제어신호를 내보낸다.
- 제어 장치는 메모리로부터 가져온 120과 100을 ALU에 보낸다
- ALU는 연산을 수행하고 레지스터에 결과를 담는다
- 앞과 같은 방식으로 메모리 2번지 명령어를 불러온 후, 제어 장치가 해석하고 220이라는 앞선 결과를 레지스터에서 메모리 쓰기 제어신호를 보내 메모리 5번지에 저장한다.
ALU와 제어장치
ALU가 받아들이는 정보
- From 레지스터 - 피연산자
- From 제어장치 - 제어 신호
계산을 위해 필요한 정보들을 담는다고 생각하면 된다.
ALU가 내보내는 정보
- To. 레지스터 - 결과값 (숫자,문자, 주소, ... )
- CPU가 메모리에 접근하는 속도보다 레지스터에 접근하는 속도가 빠르기 때문에 결과값은 레지스터에 담는다.
- To. 플래그 레지스터- 플래그 (연산 결과에 대한 부가 정보) ex) 연산결과가 음수라면 '연산 결과가 음수!'라는 정보가 플래그에 담김
ALU에서 제공하는 주요 플래그
종류 | 의미 |
부호 플래그 | 연산한 결과의 부호를 나타낸다. ex) 부호 플래그가 1일 경우는 음수, 0일 경우는 양수 |
제로 플래그 | 연산 결과가 0인지 여부를 나타낸다. ex) 1일 경우 연산 결과는 0 |
캐리 플래그 | 연산 결과 올림수나 빌림수가 발생했는지를 나타낸다. ex) 1일 경우 올림수나 빌림수가 발생했음을 의미 |
오버플로우 플래그 | 오버플로우가 발생했는지를 나타낸다. |
인터럽트 플래그 | 인터럽트가 가능한지를 나타낸다. |
슈퍼바이저 플래그 | 커널 모드로 실행 중인지, 사용자 모드로 실행 중인지를 나타낸다. |
제어장치가 받아들이는 정보
- 클럭 - 컴퓨터의 모든 부품을 일사불란하게 움직일 수 있게 하는 시간 단위
- From 명령어 레지스터(레지스터 종류 중 하나)- 해석할 명령어
- From 플래그 레지스터 - 플래그
- 제어장치가 명령어 레지스터로부터 명령어를 받으면, 명령어 해석을 위해 해당 명령에 대한 플래그도 꼭 필요함!
제어장치가 내보내는 정보
- To. 레지스터 (레지스터에 행동 명령) - 제어 신호
- To. ALU (수행할 연산 지시) - 제어신호
- To. 메모리 - 제어 신호 (CPU 외부에 전달)
- To. 입출력 장치 - 제어 신호 (CPU 외부에 전달)
레지스터
레지스터는 CPU 내부의 작은 임시저장장치로, 프로그램 속 명령어와 데이터는 실행 전후로 레지스터에 저장한다.
CPU 내부에는 다양한 레지스터가 있고, 각기 다른 역할을 가진다.
레지스터의 종류 (CPU마다 살짝씩 다름)
1. 프로그램 카운터 - 메모리에서 가져올 명령어의 주소(메모리에서 읽어들일 명령어의 주소를 저장)
2. 명령어 레지스터 - 해석할 명령어 (방금 메모리에서 읽어 들인 명령어) -> 이 명령어를 제어장치가 받아들여서 해석
3. 메모리 주소 레지스터 - 메모리의 주소 (CPU가 메모리로부터 읽어 들이고자 하는 주소를 주소 버스로 보낼 때 거치는 레지스터)
4. 메모리 버퍼 레지스터 - 메모리와 주고받을 값 (데이터와 명령어 / CPU가 정보를 데이터 버스로 주고받을 때 거치는 레지스터)
다음 동작에서 위 4가지의 레지스터가 어떻게 쓰이는지 살펴보자.
CPU가 실행하고자 하는 프로그램이 메모리에 다음과 같이 저장돼있을 때 CPU 속 레지스터들이 어떻게 쓰여질까? (1000번지부터 실행한다고 가정한다.)
메모리 | |
1101 | 1000번지 |
1111 | 1001번지 |
--- | --- |
1000 | 1500번지 |
- 우선, 1000번지의 명령어를 메모리로부터 가져와야 하므로 프로그램 카운터에 1000 이 저장된다.
- 메모리로부터 1000번지의 명령을 가지고 오기 위해서 다음으로 불러올 명령어의 주소값인 1000이 메모리 주소 레지스터에 저장된다.
- 메모리는 1000번지에 저장된 값인 1101을 CPU에 보내주고, 이는 메모리 버퍼 레지스터에 저장된다. 이 때, 프로그램 카운터에는 +1 해줘서 (다음으로 수행할 명령은 1001번지에 있으므로 -> 이는 프로그램을 순차적으로 실행할 수 있는 원리와 같다.) 1001이 저장된다.
- 방금 읽어들인 1101 명령어를 해석하기 위해서 명령어 레지스터에 1101을 담는다.
다음과 같이 순차적인 명령이 끊기는 경우도 있다. 이렇게 되면 프로그램카운터가 1씩 증가하지 않겠죠?
- 특정 메모리 주소로 실행 흐름을 이동하는 명령어 실행시 ex) JUMP, CONDITIONAL, CALL
- 인터럽트 발생 시
- ETC ...
5. 플래그 레지스터 - 연산 결과 또는 CPU 상태에 대한 부가적인 정보
6. 범용 레지스터 - 다양하고 일반적인 상황에서 자유롭게 사용 (명령어, 데이터 등등 범용적으로 담을 수 있음)
7. 스택 포인터 - 주소 지정에 사용 (스택의 꼭대기 가리킴)
8. 베이스 레지스터 - 주소 지정에 사용 (기준 주소 저장)
특정 레지스터를 이용한 주소 지정 방식 (위에서 7,8번에 해당하는 레지스터와 관련된 내용)
스택 주소 지정 방식 : 스택과 스택 포인터를 이용한 주소 지정 방식
스택 포인터: 스택의 꼭대기를 가리키는 레지스터 ex) 스택포인터에 4번지가 저장돼있다면, 스택이 4번지까지 채워져있다는 의미이다.
엥 ?????? 갑자기 스택? 그럼 스택은 어디 있는 걸까?????
-> 메모리 안에 있다. (메모리는 코드, 데이터, 스택, 힙 영역으로 구분 되는데 그 중 스택 영역이 여기서 의미하는 스택이다. 이건 운영체제에서 공부 고고)
변위 주소 지정 방식: 오퍼랜드 필드의 값(변위 / 시작 값과 얼마나 떨어져있는지 )과 특정 레지스터(프로그램 카운터 or 베이스 레지스터)의 값을 더하여 유효 주소를 얻는 방식
- 상대 주소 지정 방식 : 오퍼랜드 필드의 값과 프로그램 카운터의 값을 더하여 유효 주소 얻기
- 베이스 레지스터 주소 지정 방식 : 오퍼랜드 필드의 값과 베이스 레지스터의 값을 더하여 유효 주소 얻기 (기준 주소로부터 변위 값만큼 떨어진 코드 실행!)
명령어 사이클과 인터럽트
CPU는 정해진 흐름대로 명령어를 실행한다. 여기서 정해진 흐름을 명령어 사이클 이라고 한다. 가끔 이렇게 정해진 흐름을 끊는 신호가 오는데 그게 바로 인터럽트이다.
명령어 사이클
메모리에 저장된 명령어를 실행하려면?
- 인출 사이클: 메모리에 있는 무언가를 CPU로 가져 온다
- 실행 사이클: 갖고왔으면 실행해야겠죠..?
일반적으로 명령어 사이클은 인출-실행-인출-실행- ... 이런 과정이 반복 된다.
그런데, CPU로 명령어를 가져와도 바로 실행이 불가능한 경우도 있다.
- 간접 사이클 - 몇 번 더 메모리 접근을 해야하는 경우
인출 사이클 → 간접 사이클 → 실행 사이클 → 인터럽트 사이클
인터럽트
- CPU가 꼭 주목해야 할 때, CPU가 얼른 처리해야 할 다른 작업이 생겼을 때 발생
동기 인터럽트(예외)
CPU가 예기치 못한 상황을 접했을 때 발생 (어? 이 상황은 뭐지.. 잠깐 실행을 중단하고 이걸 처리해야겠다)
- 폴트
- 트랩
- 중단
- 소프트웨어 인터럽트
비동기 인터럽트(하드웨어 인터럽트)
주로 입출력장치에 의해 발생 (다른 하드웨어가 보내주는 인터럽트)
알림(세탁기 완료 알림, 전자레인지 조리 알림)과 같은 역할
CPU가 인터럽트 요청을 받아들이려면 항상 명령어 실행을 끝내고 플래그 레지스터 속의 인터럽트 플래그를 확인한다
입출력장치는 CPU에 비해 느리다.
- 인터럽트가 없다면 CPU는 주기적으로 프린트(입출력 장치) 완료 여부를 확인하기 위해 주기적으로 살펴봐야 한다.
- 다 됐나? 아니네. 다 됐나? 아니네 ... (무한 반복....)
- 인터럽트가 있다면 CPU는 입출력장치에게 다 되면 알려줘~ 해두고 다른 일을 하고 있으면 된다. 더 효율적!
하드웨어 인터럽트의 처리 순서
- 입출력 장치는 CPU에 인터럽트 요청 신호를 보낸다.
- CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 인터럽트 여부를 확인한다.
- CPU는 인터럽트 요청을 확인하고 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인한다.
- 인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 백업한다.
- CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행한다.
- 인터럽트 서비스 루틴 실행이 끝나면 4에서 백업해둔 작업을 복구하여 실행을 재개한다.
- 인터럽트 요청 신호 - CPU의 작업을 방해하는 인터럽트에 대한 요청 (지금 끼어들어도 되나요~? 라는 내용의 신호)
- 인터럽트 플래그 - 인터럽트 요청 신호를 받아들일지 무시할지를 결정하는 비트
- 인터럽트 서비스 루틴 - 메모리에 저장돼있는 일종의 (인터럽트를 처리하는) 프로그램. 인터럽트가 발생했을 때 해당 인터럽트를 어떻게 처리하는지 적혀있는 프로그램
- 인터럽트 벡터 - 각각의 인터럽트를 구분하기 위한 정보 (인터럽트 서비스 루틴의 시작 주소를 포함하는 인터럽트 서비스 루틴의 식별 정보 / 인터럽트 벡터를 보니 이 인터럽트 서비스 루틴의 시작점은 여기구나~ 하고 알 수 있게 도와줌)
'알고리즘' 카테고리의 다른 글
[알고리즘] 백준 1865 - 웜홀 / 벨만 포드 알고리즘 (1) | 2024.01.06 |
---|---|
[알고리즘] 백준 1753 - 최단경로 (0) | 2024.01.04 |
[알고리즘] 프로그래머스 - 프로세스 (0) | 2024.01.03 |
[알고리즘] 프로그래머스 - 두 큐 합 같게 만들기 (2) | 2024.01.03 |
[알고리즘] 백준 1504 - 특정한 최단 경로 (0) | 2024.01.02 |