[혼공학습단 12기] 혼자 공부하는 컴퓨터구조+운영체제

[혼공컴운] 2주차 / 화이팅 >ㅁ<

예지S2 2024. 7. 13. 21:08

2주차 공부 시작! 저번주에는 급하게 읽고 정리했다면 이번주는 월요일부터 열심히 나눠서 읽었다. 이번주는 저번주랑은 다르게 처음 들어보는 단어가 많아서 여러번 다시 읽는 것을 반복했다. 처음 읽을 때는 이게 뭔소리지.. 싶은데 2번, 3번 읽으니까 이게 이런 내용이구나하고 이해되서 신기하고 재미있게 읽을 수 있었다! 가볍게 여러번 읽어보라는게 어떤 의미인지 알 수 있었다! 시간을 넉넉하게 두고 천천히 여러번 읽으니까 처음보는 내용이 머리에 잘 들어왔당ㅎㅎ

 

Chapter 04 CPU의 작동 원리

04-1 ALU와 제어장치

CPU 내부에는 계산을 담당하는 ALU와 명령어를 읽어들이고 해석하는 제어장치, 작은 임시 저장 장치인 레지스터라는 구성요소가 있다.

 

1. ALU

ALU는 레지스터를 통해 피연산자를 받아들이고, 제어장치로부터 수행할 연산을 알려주는 제어신호를 받아들인다. 받아들인 피연사자와 제어 신호로 산술 연산, 논리 연산 등 다양한 연산 수행

 

연산을 수행한 결과값은 바로 메모리에 저장되지 않고 일시적으로 레지스터에 저장된다.

CPU가 메모리에 접근하는 속도 << 레지스터에 접근하는 속도

연산할 때 마다 결과를 메모리에 저장한다면 프로그램의 실행 속도가 늦어진다.

 

ALU는 계산결과와 더불어 플래그를 내보낸다. 때때로 ALU는 결괏값뿐만 아니라 연산 결과에 대한 추가적인 정보를 내보내야 하는데, 이러한 연산 결과에 대한 추가적인 상태 정보를 플래그하고 한다.

플래그들은 플래그 레지스터에 저장되는데, 이름 그대로 플래스 값들을 저장하는 레지스터에 저장된다. 연산 결과에 따른 추가적인 정보, 참고 정보를 얻을 수 있다.

 

2. 제어장치

제어장치는 제어신호를 내보내고, 명령어를 해석하는 부품이다. 컴퓨터 부품들은 관리하고 작동시키기 위한 일종의 전기 신호이다.

 

1) 제어장치는 클럭 신호를 받아들인다.

클럭이란? 컴퓨터의 모든 부품을 움직일 수 있게 하는 시간 단위이다. 클럭에 주기에 맞춰 한 레지스터에서 다른 레지스터로 데이터가 이동되거나, ALU에서 연산이 수행되거나, CPU가 메모리에 저장된 명령어를 읽어 들이는 것이다.

 

2) 제어장치는 '해석해야 할 명령어'를 받아들인다.

명령어 레지스터로부터 해석할 명령어를 받아들이고 해석한 뒤, 제어 신호를 발생시킨다.

 

3) 제어장치는 플래그 레지스터 속 플래그 값을 받아들인다.

플래그 값을 받아들이고 이를 참고하여 제어 신호를 발생시킨다.

 

4) 제어장치는 시스템 버스, 그 중에서도 제어 버스로 전달된 제어 신호를 받아들인다.

제어장치는 제어버스를 통해 외부로부터 전달된 제어 신호를 받아들이기도 한다.

 

제어장치는 CPU의 외부와 내부로 제어 신호를 내보낸다. CPU 외부에 제어 신호를 전달한다는 말은 제어 벗로 제어 신호를 내보낸다는 말과 같다. 외부로 내보내는 제어 신호에는 크게 메모리에 전달하는 제어 신호와 입출력장치에 전달하는 제어 신호가 있다. 내부에 전달하는 제어 신호에는 크게 ALU에 전달하는 제어 신호와 레지스터에 전달하는 제어 신호가 있다. 

 

 

04-2 레지스터

레지스터에 저장된 값만 잘 관찰해도 프로그램의 실행 흐름을 파악할 수 있다.

 

1. 반드시 알아야 할 레지스터

많은 CPU가 공통으로 포함하고 있는 여덟 개의 레지스터를 학습한다.

프로그램 카운터 메모리에서 가져올 명령어의 주소, 즉 메모리에서 읽어 들일 명령어의 주소를 저장
명령어 레지스터 메모리에서 읽어 들인 명령어를 저장하는 레지스터
메모리 주소 레지스터 메모리의 주소를 저장하는 레지스터
메모리 버퍼 레지스터 메모리와 주고받을 값(데이터와 명령어)을 저장하는 레지스터
플래그 레지스터 ALU 연산 결과에 따른 플래그를 저장하는 레지스터
범용 레지스터 다양하고 일반적인 상황에서 자유롭게 사용할 수 있는 레지스터
스택 포인터 스택의 꼭대기를 가리키는 레지스터로 스택의 어디까지 데이터가 채워져 있는지에 대한 표시
스택 주소 지정 방식에 사용된다.
베이스 레지스터 기준이 되는 레지스터
베이스 레지스터 주소 지정 방식에서 사용된다.

 

2. 특정 레지스터를 이용한 주소 지정 방식(1) : 스택 주소 지정 방식

스택 주소 지정 방식은 스택과 스택 포인터를 이용한 주소 지정 방식이다.

스택은 메모리 안에 스택처럼 사용할 영역이 정해져 있다. 이를 스택 영역이라고 한다. 이 영역은 다른 주소 공간과는 다르게 스택처럼 사용하기로 암묵적으로 약속된 영역이다.

 

3. 특정 레지스터를 이용한 주소 지정 방식(2) : 변위 주소 지정 방식

변위 주소 지정 방식은 오퍼랜드 필드의 값과 특정 레지스터의 값을 더하여 유효 주소를 얻어내는 주소 지정 방식이다. 변위 주소 지정 방식을 사용하는 명령어는 연산 코드 필드, 레지스터 필드, 오퍼랜드 필드가 있다. 이때, 변위 주소 지정 방식은 오퍼랜드 필드의 주소와 어떤 레지스터를 더하는지에 따라 상대 주소 지정 방식, 베이스 레지스터 주소 지정 방식 등으로 나뉜다.

상대 주소 지정 방식 오퍼랜드와 프로그램 카운터의 값을 더하여 유효 주소를 얻는 방식
특정 주소의 코드를 실행할 때 사용
베이스 레지스터 주소 지정 방식 오퍼랜드와 베이스 레지스터의 값을 더하여 유효 주소를 얻는 방식
기준 주소로부터 얼마나 떨어져 있는 주소에 접근할 것인지를 연산하여 유효 주소를 얻어낸다

 

 

04-3 명령어 사이클과 인터럽트

하나의 명령어를 처리하는 정형화된 흐름을 명령어 사이클이라고 하고, 간혹 흐름이 끊어지는 상황이 발생하는데, 이를 인터럽트라고 한다.

 

1. 명령어 사이클

컴CPU는 명령어들을 하나씩 실행한다. 이 때 프로그램 속 각각의 명령어들은 일정한 주기가 반복되며 실행되는데, 이 주기를 명령어 사이클이라고 한다.

명령어 사이클의 첫 번째 과정은 명령어를 메모리에서 CPU로 가지고 오는 것으로 인출 사이클이라고 한다. 두 번째 과정은 CPU로 가져온 명령어를 실행하는 단계로 실행 사이클이라고 한다. 제어장치가 명령어 레지스터에 담긴 값을 해석하고, 제어 신호를 발생시키는 단계이다. 명령어는 일반적으로 인출과 실행 사이클을 반복하며 실행된다.

명령어를 인출하여 CPU로 가져와도 곧바로 실행할 수 없는 경우도 있다. 예를 들어 간접 주소 지정 방식은 오퍼랜드 필드에 유효 주소의 주소를 명시하기 때문에 명령어를 인출하여 CPU로 가져왔다 하더라도 실행 사이클에 바로 돌입할 수 없다. 명령어를 실행하기 위해서는 메모리 접근을 한 번 더 해야한다. 이러한 단계를 간접 사이클이라고 한다.

 

2. 인터럽트

CPU가 수행 중인 작업은 방해를 받아 잠시 중단될 수 있는데, CPU의 작업을 방해하는 신호를 인터럽트라고 한다.

인터럽트의 종류에는 크게 동기 인터럽트비동기 인터럽트가 있다.

동기 인터럽트 CPU에 의해 발생하는 인터럽트
프로그래밍상의 오류와 같은 예외적인 상황에 마주쳤을 때 발생하는 인터럽트
예외라고 부름
비동기 인터럽트 주로 입출력장치에 의해 발생하는 인터럽트
알림 역할
하드웨어 인터럽트라고 부름

 

1) 하드웨어 인터럽트

알림과 같은 인터럽트이다. CPU는 입출력 작업 도중에도 효율적으로 명령어를 처리하기 위해 알림과 같은 하드웨어 인터럽트를 사용한다. 

 

2) 하드웨어 인터럽트 처리 순서

① 입출력장치는 CPU에 인터럽트 요청 신호를 보낸다.

② CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 인터럽트 여부를 확인한다.

③ CPU는 인터럽트 요청을 확인하고 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인한다.

④ 인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 백업한다.

⑤ CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행한다.

⑥ 인터럽트 서비스 루틴 실행이 끝나면 ④에서 백업해둔 작업을 복구하여 실행을 재개한다.

인터럽트 요청 신호 다른 누군가가 인터럽트 하기 전에 CPU에 물어보는 것
인터럽트 플래그 하드웨어 인터럽트를 받아들일지, 무시할지 결정하는 플래그
막을 수 있는 인터럽트와 막을 수 없는 인터럽트가 존재
인터럽트 벡터 인터럽트 서비스 루틴을 식별하기 위한 정보
인터럽트 서비스 루틴의 시작 주소를 알 수 있기 때문에 특정 인터럽트 서비스루틴을 처음부터 실행할 수 있음
인터럽트 서비스 루틴 인터럽트를 처리하기 위한 프로그램으로 인터럽트 핸들러라고도 부름
인터럽트가 발생했을 때 해당 인터럽트를 어떻게 처리하고 작동해야 할지에 대한 정보로 이루어진 프로그램
명령어와 데이터로 이루어져 있음 -> 프로그램 카운터를 비롯한 레지스터들을 사용하며 실행

 

3. 예외의 종류

예외가 발생하면 CPU는 하던 일을 중단하고 해당 예외를 처리한다.

폴트(fault) 예외가 발생한 명령어부터 실행을 재개하는 예외
트랩(trap) 예외가 발생한 명령어의 다음 명령어부터 실행을 재개하는 예외
디버깅할 때 사용
중단(abort) 강제로 중단시킬 수 밖에 없는 심각한 오류를 발견했을 때 발생하는 예외
소프트웨어 인터럽트 시스템 호출이 발생했을 때

 

 

 


 

Chapter 05 CPU 성능 향상 기법

05-1 빠른 CPU를 위한 설계 기법

클럭, 멀티코어, 멀티스레드가 CPU 속도와 어떤 관계가 있는지

 

1. 클럭

클럭 속도는 헤르츠(Hz) 단위로 측정한다. 클럭 속도가 높은 CPU는 일반적으로 성능이 좋다. 그럼 클럭속도를 무작정 높이면 CPU의 속도가 빨라지는가? CPU의 발열 문제가 생기기 때문에 클럭 속도는 높이는 것은 CPU를 빠르게 만들지만, 클럭 속도만으로 CPU의 성능을 올리는 것에는 한계가 있다.

 

2. 코어와 멀티코어

CPU의 성능을 높이는 방법에는 클럭 속도를 높이는 것 외에도 코어와 스레드 수를 늘리는 방법이 있다.

명령어를 실행하는 부품을 코어라고 한다. 8코어는 여덟개의 코어가 CPU에 들어있다는 뜻이다. 8코어처럼 코어를 여러 개 포함하고 있는 CPU를 멀티코어 CPU 또는 멀티코어 프로세서라고 한다. 멀티코어는 CPU 내에 명령어를 처리하는 일꾼이 여러 명이 있는 것과 같다. 코어의 개수가 늘어나면 CPU의 연산 속도 또한 빨라지지만 꼭 코어 수에 비례하여 증가하지는 않는다.

 

3. 스레드와 멀티스레드

스레드의 사전적 의미는 '실행 흐름의 단위'이다. 스레드에는 CPU에서 사용되는 하드웨어적 스레드가 있고, 프로그램에서 사용되는 소프트웨어적 스레드가 있다.

하드웨어적 스레드 - 하나의 코어가 동시에 처리하는 명령어 단위
- 예를 들어 2코어 4스레드는 명령어를 실행하는 부품을 두 개를 포함하고, 한 개의 부품이 두 개의 명령어를 처리하여 전체적으로 보았을 때 한 번에 네 개의 명령어를 처리할 수 있는 CPU를 의미
- 하나의 코어로 여러 명령어를 동시에 처리하는 CPU를 멀티스레드 프로세서 또는 멀티스레드 CPU라고 한다.
소프트웨어적 스레드 - 하나의 프로그램에서 독립적으로 실행되는 단위

 

멀티스레드 프로세서를 실제로 설계하는 일은 매우 복잡하다. 가장 큰 핵심을 레지스터이다. 하나의 코어로 여러 명령어를 동시에 처리하려면 레지스터를 여러개 가지고 있으면 된다. 2코어 4스레드 CPU를 예시로 들면 한 개의 코어에 레지스터 세트가 한 개이면 한 개의 명령어를 처리하기 위한 정보들을 기억하지만, 두 개의 레지스터 세트가 있다면 두 개의 명령어를 처리하기 위한 정보들을 기억할 수 있다. 즉 하나의 코어에 두 개의 레지스터 세트가 있다면 두 개의 명령어가 동시에 실행이 된다.

프로그램 입장에서 봤을 때는 한 번에 하나의 명령어를 처리하는 CPU가 네 개가 있는 것처럼 보인다. 그래서 하드웨어 스레드를 논리 프로세서라고 부르기도 한다.

 

05-2 명령어 병렬 처리 기법

우CPU를 한시도 쉬지 않고 작동시키는 기법인 명령어 병렬 처리 기법에 대해

 

1. 명령어 파이프라인

명령어가 처리되는 과정 : 명령어 인출 → 명령어 해석 → 명령어 실행 → 결과 저장

같은 단계가 겹치지만 않는다면 CPU는 각 단계를 동시에 실행할 수 있다. 명령어를 겹쳐서 수행하면 명령어를 하나하나 실행하는 것보다 훨씬 더 효율적으로 처리할 수 있다.

명령어를 명령어 파이프라인에 넣고 동시에 처리하는 기법은 명령어 파이프라이닝이라고 한다. 파이프라이닝이 특정한 상황에서는 실패하는 경우도 있다. 이러한 상황을 파이프라인 위험이라고 한다. 파이프라인 위험에는 크게 데이터 위험, 제어 위험, 구조적 위험이 있다.

데이터 위험 명령어 간 '데이터 의존성'에 의해 발생
의존적인 두 명령어를 무작정 동시에 실행하려고 하면 파이프라인이 제대로 작동하지 않음
제어 위험 프로그램 카운터의 갑작스러운 변화
프로그램 실행 흐름이 바뀌어 명령어가 실행되면서 프로그램 카운터 값에 갑작스러운 변화가 생긴다면 명령어 파이프라인에 미리 가지고 와서 처리 중이었던 명령어들은 쓸모가 없어짐
구조적 위험 서로 다른 명령어가 동시에 ALU, 레지스터 등과 같은 CPU 부품을 사용하려고 할 때 발생

 

2. 슈퍼스칼라

CPU 내부에 여러 개의 명령어 파이프라인을 포함한 구조를 슈퍼스칼라라고 한다.

슈퍼스칼라 구조로 명령어 처리가 가능한 CPU를 슈퍼스칼라 프로세서 또는 슈퍼스칼라 CPU라고 한다. 이론적으로는 파이프라인 개수에 비례하여 프로그램 처리 속도가 빨라지지만 실제로는 반드시 파이프라인의 개수이 비례하여 빨라지지는 않는다. 여러 개의 파이프라인을 이용하면 하나의 파이프라인을 사용할 때보다 데이터 위험, 제어 위험, 구조적 위험을 피하기 까다롭다.

 

3. 비순차적 명령어 처리

명령어를 순차적으로 처리하지 않는 기법이다. 명령어 파이프라이닝, 슈퍼스칼라 기법은 모두 여러 명령어의 순차적인 처리를 상정한 방법이다. 코드를 이루는 명령어들 중에 서로 데이터 의존성이 전혀 없는, 순서를 바꿔 처리해도 수행 결과에 영향을 미치지 않는 명령어들이 있다.

순서를 바꿔 실행해도 무방한 명령어를 먼저 실행하여 명령어 파이프라인이 멈추는 것을 방지하는 기법을 비순차적 명령어 처리 기법이라고 한다.

 

05-3 CISC와 RISC

CPU의 언어인 ISA와 각기 다른 성격의 ISA를 기반으로 설계된 CISCRISC를 학습

 

1. 명령어 집합

CPU가 이해할 수 있는 명령어들의 모음을 명령어 집합 또는 명령어 집합 구조(ISA)라고 한다.

같은 소스 코드로 만들어진 같은 프로그램이라 할지라도 ISA가 다르면 CPU가 이해할 수 있는 명령어도 어셈블리어도 달라진다.

ISA가 다르면 제어장치가 명령어를 해석하는 방식. 사용되는 레지스터의 종류와 개수, 메모리 관리 방법 등 많은 것이 달라진다.

 

2. CISC

CISC는 Complex Instruction Set Computer의 약자이다. 그대로 해석하면 '복잡한 명령어 집합을 활용하는 컴퓨터'를 의미한다. 이름 그대로 복잡하고 다양한 명령어들을 활용하는 CPU 설계 방식이다.

CISC는 다양하고 강력한 기능의 명령어 집합을 활용하기 때문에 명령어의 형태와 크기가 다양한 가변 길이 명령어를 활용한다.

메모리를 최대한 아끼며 개발해야 했던 시절에 인기가 높았다. 하지만 CISC에는 치명적인 단점이 있는데, 활용하는 명령어가 워낙 복잡하고 다양한 기능을 제공하기 때문에 명령어의 크기와 실행되기까지의 시간이 일정하지 않다. 그리고 복잡한 명령어 때문에 명령어 하나를 실행하는 데에 여러 클럭 주기를 필요로 한다. 이러한 단점 때문에 파이프라인이 효율적으로 명령어를 처리할 수 없다. 즉 규격화되지 않은 명령어가 파이프라이닝을 어렵게 만들었다.

 

3. RISC

RISC는 Reduced Instruction Set Computer의 약자이다. CISC와는 달리 짧고 규격화된 명령어, 되도록 1클럭 내외로 실행되는 명령어를 지향한다. 즉 고정 길이 명령어를 사용한다. 고정 길이 명령어를 사용하기 때문에 명령어 파이프라이닝에 최적화되어 있다.

RISC는 메모리에 직접 접근하는 명령어를 두 개로 제한하여 메모리 접근을 단순화, 최소화하는 대신 레지스터를 적극적으로 활용한다.

CSIC RISC
복잡하고 다양한 명령어 단순하고 적은 명령어
가변 길이 명령어 고정 길이 명령어
다양한 주소 지정 방식 적은 주소 지정 방식
프로그램을 이루는 명령어의 수가 적음
(사용 가능한 명령어의 개수가 많음)
프로그램을 이루는 명령어의 수가 많음
(명령어 개수가 적기 때문에 많은 명령으로 프로그램 작동)
여러 클럭에 걸쳐 명령어 수행 1클럭 내외로 명령어 수행
파이프라이닝하기 어려움 파이프라이닝하기 쉬움

 


 

숙제

125p. 확인문제 2번

설명에 맞는 레지스터를 보기에서 찾아 빈칸을 채워 보세요.

  • 플래그 레지스터 : 연산 결과 혹은 CPU 상태에 대한 부가 정보를 저장하는 레지스터
  • 프로그램 카운터 : 메모리에서 가져올 명령어의 주소를 저장하는 레지스터
  • 범용 레지스터 : 데이터와 주소를 모두 저장할 수 있는 레지스터
  • 명령어 레지스터 : 해석할 명령어를 저장하는 레지스터

 

155p. 확인문제 4번

다음 그림은 멀티코어 CPU를 간략하게 도식화한 그림입니다. 빈칸에 알맞은 용어를 써 넣으세요.

 

코어

 


 

추가숙제

코어와 스레드, 멀티코어와 멀티스레드의 개념 정리

코어 : 명령어를 실행할 수 있는 '하드웨어 부품'

스레드 : 명령어를 실행하는 단위

멀티코어 : 명령어를 실행할 수 있는 하드웨어 부품이 CPU 안에 두 개 이상 있는 CPU

멀티스레드 : 하나의 코어로 여러 개의 명령어를 동시에 실행할 수 있는 CPU