computer system의 기본 요소
processor, main memory, system bus + I/O modules
각 모듈(processor, main memory, I/O modules) 간의 정보 전달은 system bus를 통해서 수행된다.
CPU(processor)의 기본 요소
CU(Control Unit), ALU(Arithmetic Logical Unit), Register + cache
CU와 ALU는 HW이고 register는 logical unit이기 때문에 OS에서는 register가 중요
register는 크게 register for data I/O, control and status registers, user-visible register로 나뉠 수 있다.
Registers for data I/O
Memory Address Register(MAR)
CPU에서 Memory에 저장된 data를 가져오거나 쓰기 위해(for I/O) 할당된 주소를 가리키고 있는 register.
해당 register의 주소 값을 참조해 memory에 있는 데이터를 가져오거나 쓸 수 있다.
Memory Buffer Register(MBR)
- memory에 쓰여질 데이터를 MBR에 저장한 뒤 MAR의 주소로 이동해 데이터를 저장(STORE)
- MAR 주소 값에 저장되어 있는 memory data를 MBR에 저장(LOAD)
I/O Address Register, I/O Buffer Register
memory 외의 다른 I/O device(HDD, mouse ,keyboard ..)의 데이터를 가져오거나 쓰기 위해 각 I/O마다 할당된 Address Register와 Buffer Register가 존재한다.
Control and Status Registers
PC(Program Counter)
CPU가 다음에 실행할 명령어의 위치 주소를 갖고 있는 register이다.
IR(Instruction Register)
PC가 가리키는 주소의 코드를 저장하고 있는 register이다.
우선 fetch 명령을 통해 PC가 가리키는 주소에 저장되어 있는 명령어를 IR에 저장한 뒤
execute 명령을 통해 IR에 저장되어 있는 명령어를 debugging해 실행한다.

PSW(Program Status Word)
현재 명령어의 상태를 나타내는 flag로 이루어져있는 register로 3가지로 나뉘어진다.
- Condition codes
- 현재 코드의 실행 결과에 대한 정보를 갖고 있는 register.
- 현재 코드의 결괏값의 상태를 positive result, negative result, zero, overflow 등으로 표시
- conditions code를 통해 조건문과 같은 식을 검사하거나, error 발생 시 즉각적으로 대처할 수 있게 된다.
- Interrupt enable/disable
- 해당 명령어에서 interrupt를 허용할 것인지를 나타내는 flag
- Supervisor/user mode
- 현재 instruction을 실행 시킨 주체의 권한을 표시하는 flag(kernel or user)
Overview

Example of program execution

명령어 format이 위와 같이 4word로 이루어져 있다고 할 때, 1word가 연산자이고 3word가 피연산자이다.
즉 2~4word에 해당하는 주소의 값에 1word 연산을 적용하는 것

- PC주소로 가 코드를 IR에 저장
- IR 코드를 decode
Interrupt
interrupt는 기본적으로 프로세스의 명령을 중간에 정지시키는 기능이다.
이러한 interrupt는
- 그 외 I/O device의 처리시간 동안 processor가 기다리지 않도록 함으로써 processor가 효율적으로 동작할 수 있도록 한다.
- 또한 interrupt는 multi programming을 구현하는 데에 필수적이고,
- 예기치 못 한 에러가 발생했을 때 코드를 정지시키도록 하는 역할도 한다.

- processor가 I/O device에게 특정 명령을 지시한다.
- 그 후 processor는 원래 process를 처리
- I/O device는 자신의 명령을 마치면 processor에게 interrupt signal을 전송
- interrupt signal을 받은 processor는 현재 수행 중인 process를 interrupt시키고 해당 작업을 완료하게 된다
⇒ cpu는 한 명령어가 끝날 때마다 interrupt signal이 발생했는지를 체크하게 된다.
⇒ 이 때 현재 작업 중인 process가 interrupt되면 안되는 경우, PSW의 interrupt disable flag를 1로 만들어 interrupt가 발생하지 않도록 한다.
base cycle + interrupt cycle

simple interrupt processing
위의 cycle에서 interrupt가 발생하게 되면 cpu는 interrupt handler 명령어를 수행해야 한다.
하지만 cpu의 register값은 한 번에 하나의 명령어밖에 저장하지 못 하기 때문에 interrupt가 끝나고 돌아와 기존 작업을 다시 수행하기 위해서는 interrupt 전의 register 값을 저장해야 한다.
따라서 interrupt 전까지의 PSW와 PC register의 정보를 control stack에 저장한 뒤 interrupt handler의 주소를 PC에 덮어쓰게 된다.

stack pointer는 memory 내의 control stack의 마지막 위치(T)를 가리키는 포인터로, interrupt 발생 시 General Register와 PC를 control stack에 하나씩 push하면서 stack pointer 값을 하나씩 감소시키게 된다.
그 후 다시 프로세스로 돌아오게 되면, stack pointer값부터 control stack의 마지막 위치(T)까지 pop을 해 register 값을 가져온 뒤, stack pointer를 다시 control stack의 마지막 위치를 가리키도록 한다.
Program Flow of Control w/wo Interrupts

interrupt가 없는 경우 I/O command(5)가 수행하는 동안 cpu가 기다려야 한다.

interrupt를 사용함으로써 cpu가 기다리는 시간 없이 명령어를 처리할 수 있게 되었다.

하지만 I/O command가 다음 I/O call 전까지 완료되지 않는 경우 문제가 발생하게 된다.
다음 I/O call은 이전 I/O call에 의해 처리된 값에 종속적이기 때문에 해당 수행이 완전히 끝나지 않은 상태로 I/O command를 수행하게 되면 데이터 무결성을 해칠 수 있다.
따라서 이러한 경우 이전 I/O command에 대한 interrupt signal을 받고 interrupt handler가 종료된 뒤(5)에야 다음 I/O call을 수행할 수 있게 되기 때문에 processor가 기다리는 시간이 발생하게 된다.
이러한 processor의 wait time을 줄이기 위해 Multiprogramming기법이 제시되었다.
Multiprogramming
여러 프로그램이 메모리에 탑제되어 있는 형식을 의미한다.
multiprogramming을 함으로써 해당 processor의 wait time이 발생하게 된다면 다른 프로그램을 처리하도록 설계해 cpu를 낭비없이 사용할 수 있게 되었다.
multiprogramming은 multiprocessing과는 다른 개념으로, multiprogramming이 선행되어야 multiprocessing을 구현할 수 있다.
Memory Hierarchy

위로 갈수록 더 빨라지지만 용량이 작아지고 가격이 비싸진다.
아래로 갈수록 더 느려지지만 용량이 커지고 가격이 싸진다.
여기서 register(CPU)와 memory(DRAM) 간의 속도 차이가 memory와 disk 간의 속도 차이보다 훨씬 크기 때문에 중간에 cache를 이용해 두 장치의 속도 차이를 줄인다.

우선 CPU는 찾고자 하는 주소가 cache memory에 있나 확인한 뒤, 있으면 cache memory에서 바로 가져오고, 없으면 main memory에서 가져오게 된다.

결국 cache를 효과적으로 사용하기 위해서는 cpu가 원하는 주소가 cache에 자주 존재해야 한다.
- locality라는 특성을 이용해 cache가 memory의 주소를 가져올 때 해당 주소의 연속적인 주소를 block단위로 가져오게 된다.
locality : 한 코드가 실행된 위치 근처에서 다음 코드가 실행된다는 가정
또한 cache에는 각 주소에 해당하는 mapping 값과 해당 주소에 있던 데이터를 모두 저장하고 있어야 하기 때문에 cache에 정보를 저장하는 데에 overhead가 발생
Cache design
cache size
- cache size와 performance 간의 관계는 log 기울기를 가진다.
- 즉 일정 cache size만으로 빈번하게 접근하는 주소를 모두 cache에 올릴 수 있기 때문이다.
block size
- 만약 데이터가 분기할 확률이 적다면 block size가 큰 것이 더 좋지만, 분기할 확률이 높다면 더 비효율적이 된다.
mapping function
- memory의 주소를 cache에서 찾을 수 있도록 도와주는 mapping function을 정해야 한다.
- 이 때 algorithm적인 방법(binary searching, heap,...)을 사용할 수 없다!
- ⇒ 속도가 매우 느려지기 때문
replacement algorithm
- cache가 가득 찼을 때, 새로운 데이터가 들어오는 경우 어떤 데이터를 내보낼 지에 대한 algorithm
- 주로 LRU(Least-Recently-Used) algorithm을 사용
write policy
cache 내에 저장된 데이터와 memory에 저장되어 있는 데이터 간 동기화 문제를 어떻게 다룰 것인가에 대한 정책
- cache 내 데이터가 업데이트될 때마다 동기화한다면 속도가 느려지겠지만 데이터 무결성을 보장할 수 있다.
- cache 내의 데이터가 제거될 때 동기화한다면 속도가 빨라지지만 데이터 무결성을 보장하지 못해 문제가 발생할 수 있다.
- 특히 위의 방법의 경우 multicore나 multiprocessor system에서 cache coherence problem을 유발할 수 있다.
최근의 computer system은 multicore나 multiprocessor를 사용하면서 각 core마다 별도의 cache(L1,L2)가 저장되어 있기 때문에 위의 cache coherence problem을 해결하기 위한 다양한 연구가 진행되었다.
Disk Cache
DRAM의 일부 영역에 disk 정보를 일부 저장해놓는 기법
I/O Process
기본적으로 I/O 장치가 직접 memory에 접근할 수 없기 때문에 가장 naive한 방법으로는 cpu가 필요한 데이터를 word 단위로 하나씩 요청해야 한다.
programmed I/O

interrupt가 없는 경우의 I/O의 정보 교환 과정
- interrupt가 없기 때문에 CPU는 한 word를 요청하고 해당 요청이 완료될 때까지 대기해야 한다.
- 그 후 한 word의 요청이 끝나면 다시 다음 word를 요청하는 방식으로 동작한다.
⇒ 이 때 memory에 word를 write하는 과정에서 다른 cpu가 I/O를 점유할 수도 있기 때문에 각 word가 끝날 때마다 다시 I/O의 현재 상태가 이용가능한지를 loop를 돌게 된다.
Interrupt-driven I/O

interrupt를 사용하는 경우의 I/O 정보 교환 과정
- interrupt를 사용함으로써 cpu가 기다리는 시간없이 I/O로부터 word를 얻을 수 있게 되었다.
- 하지만 이 역시 각 word가 끝날 때마다 다시 다음 word를 요청해야 한다는 단점이 존재한다.
Direct Memory Access by DMAC

DMA controller(DMAC)를 이용해 I/O data를 메모리에 직접 쓰는 방식
- cpu가 각 word를 기다리는 것이 아니라 cpu가 DMA에 요청하면 DMA는 cpu대신 I/O data를 모두 입력받아 memory에 직접 쓴다.
- 이와 같은 방식은 기본적으로 I/O module이 memory에 직접 접근하지 못 하도록 하기 위함으로, DMA라는 대리인을 둬 조금 더 안전하게 memory에 접근하는 것을 보장한다.
a Dual-core Design

하나의 cpu(processor)에 여러 core가 들어있는 경우이다.
이 외에도 여러 cpu가 존재하는 computer system도 존재하고, 이 때 각 cpu를 하나의 package(socket)라고 이야기한다.
같은 socket 내의 core 간의 정보이동은 빠르지만, 서로 다른 socket의 core 간의 정보이동은 느리다.
Computer Startup
os를 부팅하기 위해 ROM 내부에 있는 bootstrap program이 load된다.
bootstrap program은 operating system kernel을 memory에 load하고 실행하며, 실행된 kernel이 OS를 활성화한다.
bootstrap program을 또 load하기 위한 작은 program이 main board에 내장되어 있다. ⇒ 이렇게 재귀적인 구조를 통해 점점 computer startup을 위한 program의 크기를 줄일 수 있다.(trade-off관계!)
참고
- Operating System Concepts
- 운영체제, 한양대학교 강수용 교수님
'CS > OS' 카테고리의 다른 글
| [Operating System] Process Synchronization 1 (0) | 2024.07.27 |
|---|---|
| [Operating System] CPU Scheduling (1) | 2024.07.27 |
| [Operating System] Processes And Threads (0) | 2024.07.27 |
| [Operating System] Operating System Overview (0) | 2024.07.27 |
| [Operation System] Course Overview (0) | 2024.07.27 |