HW supprot for I/O
I/O를 쉽게 하기 위해, 각 HW는 bus에 연결되어 있어 통신이 가능해진다.
Canonical HW device
HW를 쉽게 관리하기 위해 공통된 protocol을 가지고 있다.
Write할 때 발생하는 protocol은 다음과 같다.
HW interface가 결국, 동작을 결정하게 된다. 각 친구들의 variants는 다음과 같다.
Status | Data | Control |
polling interrupts |
PIO DMA |
Special instruction Memory-mapped I/O |
Status
Interrupt이 항상 좋은 것은 아니다. Fast device라면 spin하는 것이 더 좋을 수 있다. 또한 interrupt이 계속해서 발생하는 device라면 livelock에 빠질 수도 있다. 그래서 보통 device의 time을 모르면 interrupt cost만큼 spin했다가 interrupt을 수행해 worst case performance를 보장한다. 또는 interrupt 여러개를 한번에 처리하는 방식이 있겠다.
Data
Data transfer를 최적화하려는 시도이다. Programmed I/O와 Direct Memory Access가 있다.
- PIO
- CPU가 device에 직접 data 전송
- CPU의 처리 속도가 느려짐
- DMA
- CPU가 data를 memory에 저장, device가 memory 읽음
- CPU 다른 일 가능, 처리 속도 향상
PIO대신 DMA를 사용하면, data를 device register에 작성하는 일이 없어진다.
Control
OS가 register를 read/write하는 과정을 최적화한다. Special instruction과 Memory-mapper I/O 2가지 방법이 있다.
- Special instructions
- Device port로 통신(x86: IN, OUT)
- IN: data를 port로부터 읽어옴
- OUT: data를 port에 보냄
- Memory-mapper I/O
- Device register가 메모리의 특정 주소와 연결되어 있음
- Load/store를 하면, 바로 device register에 할 수 있음
Memory-mapper I/O가 일관된 입출력 방식을 제공하기 때문에 주로 선호된다. 반면 special instruction은 매우 빠르지만, x86에 의존적이기 때문에 사용이 어려운 경우가 많다.
Variety; challenge
HW가 너무 많아지면서, 이를 모두 OS가 관리하는 것은 어려워졌다. 그래서 HW 장치들은 자신만의 driver를 가지게 되었다. 드라이버는 Linux code(약 70%) 베이스이다.
Hard Disk
Disk는 sector기반의 주소체계를 가진다. 보통 sector는 512B나 4KB로 구현된다. 주 명령어는 read/write이다. 물리적 기계로 동작하기 때문에 느리다는 특징을 가지고 있다.
Disk는 위 그림처럼 원통형 구조에 여러개의 platter로 구성되어 있다. Platter의 위, 아래에 sector가 있고 이곳에 data를 read/write할 수 있다.
Platter가 spin하면, arm에 있는 reader로 sector를 읽게 된다. Arm의 운동 과정은 다음과 같다.
- 읽을 sector의 track 찾기
- 해당 track으로 arm 이동
- platter 회전시켜서 sector 읽기(혹은 쓰기)
Time to read/write
하나의 sector를 읽기 위해 걸리는 총 시간은 다음과 같다.
Time = Seek + Rotation + transfer time
Seek time
Arm을 올바른 track으로 옮기는 시간이다. 보통 4-10ms가 소모된다.
Rotation time
Disk의 RPM에 따라 달라지는데, 보통 7200RPM을 가진다. 7200RPM이면 rotation하는 데 걸리는 시간은 다음과 같다.
- 7200 RPM = 1 min / 7200 rotations = 1 s / 120 rotations
- 8.3 ms / rotation
- Average = 4.15 ms
Transfer time
보통 100+ MB/s로 전송할 수 있다. 그래서 sector의 크기가 512B라면, 512B*(1/100MB), 즉 5 us 시간이 걸린다.
Performance
Seek과 rotation은 느리고, transfer는 충분히 빠르기 때문에 disk의 arm 이동을 신중히 해야 성능 향상이 가능해진다. 가령 sequential workload라면 seek, rotation은 문제 없어지고 random workload라면 중요해진다.
Disk performance calc.
위와 같은 disk spec이 주어진다면, 우리가 볼 것은 seek, RPM, transfer이다.
이제 performance를 계산할 수 있게 된다. 우선 sequential workload를 가정해 보고, throughput을 계산해 본다. Sequential workload이기 때문에 max transfer가 처리량이 된다. 따라서,
Sequential workload | |
치타 | 바라쿠다 |
125 MB/s | 105 MB/s |
반대로 random access workload로 가정해 보자. 이를 위해서는 우선 읽을 sector 크기를 가정해야 한다. 약 16KB라고 생각해 보자. 고려해봐야 할 것은 seek, rotation, transfer이다.
- 치타
- Seek = 4 ms
- Rotation = 1/2 * 1min/15000 * 60s/1min * 1000ms/1s = 2 ms
- Transfer = 1s/125MB * 16KB * 1000000us/1s = 125us
- Runtime = 6.1ms
- Throughput = 16KB/6.1ms * 1MB/1025KB * 1000ms/1s = 2.5MB/s
- 바라쿠다
- Seek = 9 ms
- Rotation = 1/2 * 1min/7200 * 60s/1min * 1000ms/1s = 4.1 ms
- Transfer = 1s/105MB * 16KB * 1000000us/1s = 149us
- Runtime = 13.2ms
- Throughput = 16KB/13.2ms * 1MB/1025KB * 1000ms/1s = 1.2MB/s
Random access workload | |
치타 | 바라쿠다 |
2.5 MB/s | 1.2 MB/s |
Other improvement 1: Track skew
Track number를 왼쪽처럼 지정하면, rotation 대비 arm이 이동하는 시간이 길기 때문에 한바퀴를 더 돌게 된다. 그래서 오른쪽처럼 track number를 부여한다.
Other improvement 2 : Cache
Disk에는 2MB-16MB짜리 휘발성 cache가 있다. Rotation delay 동안, track의 모든 data를 memory에 저장해서 반복해서 접근할 경우 속도를 높일 수 있다. 반대로 write할 떄는, disk에 저장하기에는 느리니까 일단 케시에 저장하고 사용하다 적당한 때에 disk에 저장한다.
I/O scheduler
CPU 스케쥴링과는 다르며 disk의 arm 위치를 고려해서 스케쥴링해야한다.
- FCFS(FIFO)
대충 seek+rotate에 10 ms가 걸린다고 생각
101, 102, 103, 701, 702, 703 // 20 ms 걸림
101, 701 , 102, 702, 103, 703 // 60 ms 걸림 - SPTF(Shortest Positioning Time First)
Arm이 빠르게 찾을 수 있는 친구부터 수행
Starvation 단점이 있음 - SCAN
앞이나 뒤로 이동하다 끝까지 가면 방향을 바꿈
Unfairness between inner and outer tracks - C-SCAN
한쪽 끝에 도달하면, 반대쪽 끝으로 이동 - Work conservation
끝내야 하는 work부터 끝내려 함
때때로, request가 있어도 그냥 wait해서 기다림
예상 스케쥴러라고도 불림
'Study > Operating System' 카테고리의 다른 글
12. File System Implementation (0) | 2023.12.14 |
---|---|
10. Semaphore (0) | 2023.12.11 |
9. Advanced lock; Locks and Condition variables (2) | 2023.12.10 |
8. Locks (0) | 2023.12.09 |
7. Stack (0) | 2023.12.08 |