경희대학교 허선영 교수님의 운영체제 수업을 기반으로 정리한 글입니다.
Computer System Basics
▶ Introduction
작성한 test.cpp는 바로 실행될 수 없어, 머신이 이해할 수 있는 머신 랭귀지(binary)로 된 실행 가능한 형태의 프로그램(Executable)으로 번역해 주어야 한다. 이때 그 번역을 할 때 사용되는 게 컴파일러이다.
test.exe는 결국 CPU가 해야 하는 명령어들을 순차적으로 저장을 하고 있는 것이다.
machine language는 CPU가 처리, 즉 실행할 수 있는 언어로 binary로 되어 있기에 사람이 명령어를 이해하는 게 어렵다.
이 머신 랭귀지를 사람이 이해할 수 있는 명령어로 표현한 게 assembly language이다. (1:1 관계)
Instruction Set Architecture (ISA)
ISA는 CPU가 처리할 수 있는 명령어의 집합으로, CPU마다 사용할 수 있는 ISA가 정해져 있다.
또한, CPU의 ISA에 따라서 CPU가 처리할 수 있는 명령어가 다르다.
때문에 컴파일러는 항상 이 CPU의 ISA에 따라서 이 프로그램을 머신 랭귀지로 번역을 해줘야 한다.
예를 들어, Intel CPU를 사용하는 컴퓨터에서 돌아가는 프로그램은 ARM CPU를 사용하는 컴퓨터에선 실행하지 못한다.
Von Neumann Architecture
대부분의 우리 컴퓨터 시스템들은 폰 노이만 구조로 되어 있다.
이러한 본 노이만 구조는 컴퓨터가 크게 두 가지, CPU와 메모리로 구성이 된다고 정의한다.
그리고 여기에 input device(키보드, 마우스)나 output device(모니터)가 연결될 수 있다.
기본적으로 컴퓨터 시스템은 프로그램을 실행하는 것인데, 프로그램을 어떤 방식으로 실행을 하냐면, 일단 메모리에 프로그램과 데이터를 모두 가지고 있다. 이때, CPU는 메모리에서 명령어를 읽어 와, ALU와 Control Unit을 가지고 명령어를 실행한다고 폰 노이만 구조에서 규정하고 있다. (가장 기본적인 컴퓨터 시스템의 구조)
※ 프로그램: CPU 명령어들을 담고 있어, CPU가 실행할 수 있는 바이너리 프로그램이다.
※ CPU = ALU + Control Unit
- ALU: Arithmetic Logic Unit의 약자로, 사칙 연산을 할 수 있는 유닛
- Control Unit: 프로그램을 컨트롤할 수 있는 유닛
Von Neumann Architecture 확장
▶ Von Neumann Architecture 확장
폰 노이만 구조를 확장한다고 하면, 기본적인 CPU와 메모리에, 추가적으로 데이터를 영구적으로 보관할 수 있는 Storage가 있다.
프로그램을 작성한 후, 컴파일해서 binary로 만든 것을 Storage에 저장한다.
그러면 이 프로그램은 시스템에 설치되어 있는 상태이고, 이 Storage 안에 있는 것을 실행할 때는 항상 스토리지에서 프로그램을 메모리로 올려야 하는데, 이게 폰 노이만 구조의 핵심이다.
추상적으로 메모리를 표현할 때 보통 byte array로 표현하는데, 그 이유는 메모리 자체가 byte 단위로 주소가 붙어있기 때문이다.
메모리에 address가 있고, 이 각각의 address가 byte(8 bits)만큼의 데이터를 저장하는 것이다.
또한, 프로그램을 실행하려면 프로그램이 어디에 위치해 있는지, 즉 실행해야 할 명령어가 어디있는지 알아야 한다.
그래서 CPU 내부에는 PC(Program Counter)라는 레지스터가 있다. PC의 역할은 CPU가 읽어야 될 명령어의 위치를 저장하는 것이고, 이를 통해 CPU는 PC가 가리키는 위치에서 명령어를 읽어 하나씩 실행하는 것이다.
memory vs storage
- memory: volatile, 휘방설이 있어 메모리에 올려놓은 데이터는 컴퓨터를 끄면 다 날아간다.
- storage: non-volatile, 비휘발성이기에 프로그램을 영구적으로 보관하거나 파일을 보관할 때 사용한다.
프로그램은 명령어의 집합일 뿐이고, 운영체제가 관리할 때는 프로세스라는 단위로 관리한다.
그래서 똑같은 프로그램을 여러 번 실행하게 되면, 각자 서로 다른 프로세스가 생기는 것이다.
※ 레지스터: 데이터를 저장하는 공간이다.
※ CPU 명령어들은 크기가 정해져 있지 않다. 1, 4, 8 byte짜리 등의 명령어가 있을 수도 있어서, 이는 CPU가 명령어를 읽어 가면서 알아서 처리하게 된다.
CPU Architecture
▶ CPU Architecture
CPU는 메인 보드에 장착할 수 있는 프로세서 유닛으로, 기본적으로 CPU엔 멀티 Core가 들어가 있다.
Core는 연산을 할 수 있는 주체로, 각각의 코어는 parallel하게 다른 연산을 처리할 수 있으며(멀티 코어 장점), 각각의 코어에는 ALU, PC, Register, Cache가 있다. 또한, 보통은 코어 간에 공유하는 다른 레벨의 Cache가 추가적으로 있다.
⭐ Storage Hierarchy
- reg
- cache
- main memory
- storage (non volitile)
컴퓨터 시스템에는 데이터를 저장할 수 있는 공간이 다양하게 있다.
그리고 이러한 스토리지마다 물리적인 특성이 다른데, 이 특성을 피라미드 형태로 표현한 것이다.
storage hierarchy에선 빠를수록 비싸고, 느릴수록 저렴하다.
우리가 데이터를 저장할 때 모든 데이터를 레지스터에 다 넣을 수 있으면 좋겠지만, 레지스터 소자 자체가 비싸서 크게 만들 수 없어, 보통 CPU는 몇십 개의 레지스터만 가지고 있다.
그래서 모든 것을 다 레지스터에 저장할 수 없기에, 여기에 저장 못하는 것을 아래 레벨인 메모리에 저장을 한다.
on-chip memory인 레지스터와 캐시는 데이터를 읽어올 때 chip 내에서 바로 가지고 올 수가 있어, 다른 것보다 훨씬 더 빠르게 접근이 가능한 메모리들이다. 하지만, 데이터를 메인 메모리에서 가져와야 되는 순간, 속도가 훨씬 느려진다.
그래서 CPU는 최대한 레지스터나 캐시의 데이터를 보관하여 사용하는 것이 CPU 입장에선 좋다.
이때 cache의 역할은 메모리에 있는 데이터를 카피해서 가지고 오는 것이다. (caching - mirroring)
다시 말해, 메인 메모리에서 자주 사용하는 것들을 CPU 칩 내부로 가지고 와서, 메모리 데이터에 빠르게 접근할 수 있게 해주는 것이 cache의 역할이다.
- cache 사용 이유: 메인 메모리에 있는 자주 쓰는 데이터들을 CPU로, 즉 처리하는 코어에 가깝게 두기 위함
※ on-chip memory: CPU 칩 위에 있다는 뜻인데, 이때 on-chip memory인 register와 cache를 빼곤, 다 off-chip memory이다. 또한, 일반적으로 off-chip memory라고 하면 main memory를 가리킨다.
What Operating Systems Do?
▶ Operating System은 하드웨어와 사용자 사이의 중간 역할
운영체제는 복잡한 구조의 하드웨어를 좀 더 논리적이고 쉬운 구조로 사용할 수 있게 해주는 것이다.
▶ Operating System의 목적
- Convenience: 사용자한테 편의성 제공 - ex) GUI
- Efficiency: 하드웨어 자원 효율성 최대화
Computer Architecture 101
Von Neumann Architecture
▶ 폰 노이만 구조
- 컴퓨터 시스템 = CPU + Memory
메모리에 유저의 프로그램을 올린다. CPU는 필요한 명령어를 받아, 이 올라간 프로그램을 실행시키는 역할을 한다.
이러한 폰 노이만 구조에서는 항상 프로그램과 데이터가 메모리에 올라가야 한다.
Hardware Organization of Typical Computing System
▶ 실제 복잡한 구조
우리가 사용하는 컴퓨터들은 마더보드(메인보드)라는 컴퓨터 부품을 연결해 주는 이 전자 회로 위에서 구성이 된다.
일반적으로 프로그램을 설치하면 디스크에 저장이 된다. 그리고 이 프로그램이 실행이 되면 프로그램이 디스크에서 메인 메모리로 올라가는데, 이렇게 되면 폰 노이만 구조, 즉 메모리에서 CPU가 이 프로그램을 읽어 처리하는 형태가 세팅이 되는 것이다.
메모리에 프로그램이 올라가면 CPU는 메인 메모리에 올라간 프로그램 명령어들을 하나씩 읽는다. 이때, 메모리 어느 부분에서 이 프로그램을 읽어야 하는지 알기 위해 CPU가 내부적으로 Program Counter(PC)라는 레지스터를 두고 있다.
PC를 통해 메모리에서 명령어를 읽어야 하는 메모리 주소를 가지고 있게 되고,
이 주소에 있는 공간에 가서 프로그램 명령어를 읽어 처리한다.
추가적으로, CPU가 데이터랑 명령어를 읽어오는 통로를 버스라고 하는데,
위 그림의 버스를 포함한 전체적인 시스템이 마더보드 위에 구현이 되어 있는 것이다.
데스크탑 기준으로 설명하면, 데스크탑용 메인보드에는 CPU, 메모리, GPU 등이 장착되지 않은 형태로 판매가 된다.
그래서 컴퓨터 시스템을 사용하려면 메인보드 위에다 CPU, 메모리를 달아야 하고, 추가적으로 GPU를 달 수 있는 등,
이렇게 달아야 프로세싱할 수 있는 컴퓨터 시스템이 된다.
이때 메인보드는 CPU와 메모리 사이에 데이터를 주고 받을 수 있는 버스가 들어가 있다.
또한, 디바이스 컨트롤러도 내장되어 있는데, 예를 들면 메인보드에는 USB 디바이스를 연결할 수 있는 소켓들이 달려 있고 USB 디바이스랑 커뮤니케이션 하려면 컨트롤러가 필요한데 이 컨트롤러가 내장되어 있어 USB로 연결만 하면 디바이스를 다 사용할 수 있는 것이다.
이렇게 데스크탑처럼 큰 시스템은 보통 CPU, 메모리, 디스크가 다 분리 가능한 형태로 되어 있는데, 스마트폰처럼 소규모 시스템에는 이 모든 게 다 합쳐져 있다. 그래서 하나의 기판 전체가 하나의 컴퓨팅 시스템이 되는 것이다.
때문에 데스크탑은 메모리, SSD 등을 업그레이드 한다는 게 가능한데,
스마트폰은 한 번에 compact하게 만드는 것이 중요하여 장착이 다 되어 나오기에 컴퓨터 시스템의 스펙을 올릴 수 없다.
노트북도 스마트폰처럼 전체 컴퓨팅 시스템이 회로로 구현이 되어 있다.
※ Graphics adapter = Graphics Card: 컴퓨터에서 그래픽을 처리하고 화면에 출력하는 장치이다. 여기서 adapter는 서로 다른 것들을 연결하거나 변환해 주는 장치라는 의미이다.
※ 위 그림 속 CPU 안엔 cache가 생략되어 있지만 실제론 CPU 안에 데이터를 가져오는 속도를 올리기 위해 cache가 존재한다.
Storage Hierarchy
▶ Storage 및 Memory를 잘 관리 및 물리적인 특성을 잘 활용해야 프로그램을 더 효율적으로 동작 시킬 수 있다.
※ optical disk: CD / magnetic tapes: 비디오 테이프
Example
▶ 폰 노이만 구조 단순화 예시
개발자들이 프로그램을 작성해서 컴파일을 해 놓으면 binary machine language로 된 명령어들로 이루어져 실행 가능한 프로그램이 파일 형태로 디스크에 저장이 된다.
디스크에 있는 것을 실행하면, 이 명령어들이 메인 메모리에 올라가게 된다. 이래야 CPU가 데이터나 명령어를 읽어 처리할 수 있다.
이때 CPU는 이 프로그램을 실행하기 위해서 필요한 명령어들, 그리고 메인 메모리에 올라간 이 프로그램 명령어들을 읽어,
추가적으로 캐싱을 한다든지 하여 명령어들을 하나씩 실행한다.
그래서 운영체제는 이러한 프로그램을 파일 단위로 관리하기에 파일에 대한 관리,
혹은 프로그램을 실행 중에 관리하는 것 등을 해주게 된다.
Multi-Core Processors
▶ multi-core CPU 칩 내부 (구현)
운영체제의 가장 기본적인 역할이 사용자가 프로그램을 실행시키고 싶을 때 이 프로그램을 리소스를 사용해 잘 실행 시키는 것이다.
여기서 문제점은 유저가 실행시켜야 되는 프로그램의 개수가 엄청 많다는 것이다.
하드웨어에서 CPU가 처리할 수 있는 것을 프로세싱 코어라고 하는데, 이러한 코어의 개수는 한정되어 있다.
따라서 노트북은 코어의 개수가 8, 16개 정도이기에 이론적으로 한 번에 8개 혹은 16개의 프로그램만 동시에 실행 할 수 있다.
근데 Operating System이 몇 천 개의 프로그램을 이 코어에 나눠서 실행시키기에 우리가 여러 개의 프로그램을 동시에 관리할 수 있는 것이다. 즉, 실제로 프로세서 코어의 개수는 적지만 Operating System이 이를 관리해 주기에 우리가 효율적으로 사용할 수 있는 것이다.
추가적으로, 위 그림에선 생략되어 있지만 CPU에는 memory controller가 있어, 데이터가 필요하면 core가 memory controller를 통해 메모리에 접근하여 데이터를 가져오게 된다.
※ cache hierarchy
- L1 d-cache: 각 코어에서 데이터 처리를 위해 초고속으로 접근 가능한 작은 데이터 전용 캐시
- L1 i-cache: 각 코어에서 명령어 실행을 위해 초고속으로 접근 가능한 작은 명령어 전용 캐시
- L2 unified cache: 코어별로 데이터와 명령어를 함께 저장하는 중간급 캐시로, L1보다 용량은 크지만 약간 느림
- L3 unified cache (shared by all cores): 모든 코어가 함께 사용하는 대용량의 마지막 캐시 계층으로, 메모리 접근 병목 완화
※ cache의 데이터 흐름
- CPU가 데이터 요청
- 먼저 L1 캐시에서 찾음 -> L1 Hit이면 즉시 사용, L1에 없으면 L2 캐시에서 찾음
- L2 캐시에서 찾음 -> L2 Hit이면 가져옴, L2에도 없으면 L3 캐시에서 찾음
- L3 캐시에서 찾음 -> L3 Hit이면 가져옴, L3에도 없으면 메인 메모리(RAM)에서 가져옴 (cache miss)
What Operating Systems Do?
Process Management
Process
프로그램을 실행시키게 되면, 이는 더 이상 프로그램이 아닌 프로세스라고 부른다.
프로세스는 운영체제가 실제 이 프로그램을 관리하는 단위라고 볼 수 있다.
프로세스가 생기면, 프로세스에게 CPU를 할당을 해주고 다시 다른 프로세스에게 할당해 주는 스케줄링이나,
프로세스가 실행 중인지 혹은 다른 데이터를 기다리는 중인지, 이러한 프로세스의 스테이트를 관리하는 것을 해준다.
이 프로세스를 관리하기 위해서 이 프로세스가 만들어졌을 때 Data Structure를 같이 만들어서 관리하게 된다.
※ 스케줄링: 여러 프로세스가 번갈아가며 사용하는 자원을 어떤 시점에 어떤 프로세스에게 자원을 할당할지 결정하는 것이다.
▶ Process
Thread
프로세스 안에 실행할 수 있는 단위이다.
▶ Thread
Process Scheduling
엄청 많은 프로세스가 있고, CPU 코어의 개수는 제한이 되어 있는,
어떻게 이 프로세스들을 프로세서 코어에 할당을 해줄 건지 결정을 하는 것이 프로세스 스케줄링이다.
Process Synchronization
▶ Process Synchronization
- 프로세스의 실행 순서가 꼬이면 프로그램 결과가 뒤바뀌는 경우가 생기기 때문에 이를 관리하기 위해 프로세스 간의 실행 순서를 정해주는 것이다.
What Operating Systems Do?
⭐ Memory Management
Main memory
▶ main memory
메인 메모리도 크기가 4기가, 8기가, 16기가 등 고정되어 있는데,
이 메인 메모리를 잘 관리해야 돌리고 싶은 많은 프로그램을 다 돌릴 수 있다.
프로그램은 그냥 메모리에 통째로 올라가지 않는다.
프로그램을 실행하기 위해서는 명령어도 있고, 변수들도 저장해야 하고, 또 다양한 데이터가 있기 때문에,
프로그램이 사용하는 데이터의 용도에 따라서 Operating System이 메모리에 프로세스를 적절하게 올린다.
변수, 프로그램의 명령어 등을 각각 저장하여 효율적으로 메모리를 사용할 수 있게 운영한다.
What Operating Systems Do?
Storage Management
▶ Storage Management
File Management
▶ File Management