[운영체제] I/O 시스템, HDD, Disk Scheduling, RAID | CPU와 디스크의 물리적 속도 차이를 극복하는 설계

컴퓨터 주변 장치들

컴퓨터 구조를 공부하다 보면, CPU나 메모리처럼 눈에 보이지 않는 전자적 신호의 흐름보다, 실제로 소리를 내며 돌아가는 하드디스크(HDD)나 키보드 같은 입출력(I/O) 장치들이 더 흥미롭게 다가올 때가 있다. 특히, "빛의 속도로 연산하는 CPU가 왜 거북이 같은 하드디스크를 기다려줘야 할까?"라는 질문은 시스템 설계자들에게 오랫동안 골치 아픈 문제였을 것이다.

오늘은 운영체제 수업에서 다룬 I/O 시스템의 계층적 구조와 데이터를 주고받는 방식, 그리고 이제는 레거시가 되어가고 있지만 여전히 스토리지의 기본 원리를 담고 있는 HDD의 물리적 구조에 대해 정리해보고자 한다. 


1. I/O 시스템의 계층 구조

처음 마더보드 설계를 봤을 때 의문이 들었다. 모든 장치를 가장 빠른 버스(Bus)에 연결하면 되지 않을까? 하지만 강의 자료를 보며 물리적 한계와 비용(Cost)이라는 현실적인 제약을 다시금 깨닫게 되었다.

버스(Bus)의 계층화

버스는 빠를수록 물리적인 길이를 짧게 유지해야 한다. 고속도로가 길어질수록 관리가 어렵고 비용이 많이 드는 것과 비슷한 이치다. 그래서 컴퓨터는 속도와 비용에 따라 버스를 계층적으로 분리한다.

I/O System Architecture

  • Memory Bus (e.g., AXI): CPU와 메인 메모리를 연결하는 가장 빠른 도로. 아주 짧고 비싸다.

  • General I/O Bus (e.g., PCIe): 그래픽 카드 같은 고성능 장치를 위한 고속 도로.

  • Peripheral I/O Bus (e.g., SCSI, SATA, USB): HDD나 마우스처럼 상대적으로 느린 장치들을 연결하는 국도. 길게 늘여서 많은 장치를 붙일 수 있다.

결국, "모든 것을 빠르게"가 아니라 "적재적소에 배치하여 가성비를 맞추는 것"이 시스템 설계의 핵심이었다. 창업을 준비하며 비즈니스 모델을 짤 때도 리소스를 효율적으로 배분해야 하듯, 컴퓨터 구조 역시 철저한 경제학 논리를 따르고 있었다.



2. 하드웨어와 소통하는 법

장치가 연결되었다면, 이제 OS가 그 장치에 일을 시켜야 한다. 이 과정에서 CPU의 소중한 시간을 어떻게 아낄 것인가가 관건이다.

(1) Polling vs Interrupt: Checking I/O event

가장 원시적인 방법은 Polling이다. CPU가 장치에게 "다 됐어?"라고 계속 물어보는 것이다(Loop를 돌며 상태 레지스터 확인).

Polling

  • 장점: 구현이 쉽고 직관적이다.

  • 단점: 장치가 느리다면 CPU는 그 시간 동안 아무것도 못 하고 낭비(Waste)된다.


그래서 등장한 것이 Interrupt다. CPU는 명령만 내리고 다른 프로세스를 처리하다가(Context Switch), 장치가 일을 마치면 신호를 보내 CPU를 깨우는 방식이다.

Interrupt


  • 생각해볼 점: 무조건 인터럽트가 좋을까? 만약 장치가 엄청나게 빨라서 CPU가 돌아서자마자 인터럽트를 건다면, 오히려 컨텍스트 스위칭 비용 때문에 손해다. 그래서 "장치가 빠르면 Polling, 느리면 Interrupt"가 정답에 가깝다.


(2) PIO(Programmed I/O) vs DMA(Direct Memory Access): Transferring the data between memory and device

데이터를 옮기는 주체도 중요하다. 초창기 PIO 방식에서는 CPU가 데이터를 메모리에서 장치로 일일이 복사해줬다. 단순 반복 작업에 전문 인력(CPU)을 쓰는 꼴이다. 이 비효율을 해결하기 위해 DMA 컨트롤러가 도입되었다.

  • DMA: CPU는 "A에서 B로 100MB 옮겨줘"라고 DMA에게 시키고 잔다. DMA가 복사를 끝내면 그때 인터럽트를 건다. 덕분에 CPU는 데이터 이동이라는 단순 노동에서 해방되었다.

PIO
DMA


(3) I/O Instruction vs Memory-mapped I/O: Addressing the device

그렇다면 CPU는 수많은 장치 중 특정 장치(Device)를 어떻게 콕 집어서 데이터를 보낼까? 여기에는 두 가지 철학이 존재한다.

  • I/O Instruction (Port-mapped I/O):

    • CPU가 입출력을 위한 별도의 명령어(예: x86의 in, out)를 가지고 있는 방식이다.

    • 각 장치는 고유한 '포트(Port)' 번호를 가지며, CPU는 이 포트 번호를 통해 장치를 호출한다. 마치 "101호로 택배 보내"라고 별도의 우편 시스템을 쓰는 것과 같다.

    • 보통 이러한 명령어는 특권(Privileged) 명령어로, OS 커널 모드에서만 실행 가능하다.


  • Memory-mapped I/O:

    • 장치의 레지스터를 메모리 주소 공간에 매핑해버리는 방식이다.

    • CPU 입장에서는 그저 메모리의 특정 번지에 데이터를 쓰거나 읽는 것(load, store)처럼 보이지만, 실제 하드웨어는 그 주소로 가는 요청을 가로채서 해당 장치로 보낸다.

    • 별도의 I/O 명령어가 필요 없고, C언어 포인터처럼 다룰 수 있어 유연하다. 현대적인 시스템 구조에서는 이 방식이 널리 쓰인다.

MMIO




3. HDD (Hard Disk Drives)

이제 스토리지의 대명사였던 HDD를 들여다보자. SSD가 보편화되었지만, HDD의 구조를 이해하는 것은 여전히 데이터 접근 시간(Access Time)의 본질을 이해하는 데 중요하다. (보다 자세한 내용이 궁금하다면 지난 시스템프로그래밍 글을 참고하자. 이 글에서는 운영체제의 관점에서 Disk scheduling과 RAID를 중심으로 알아보고자 한다)

기계적인 움직임의 미학

HDD는 전자 장치라기보다 정밀 기계에 가깝다.

  • Platter: 데이터가 저장되는 둥근 원판.

  • Spindle: 플래터를 회전시키는 모터. (보통 7200 RPM, 10000 RPM 등)

  • Head & Arm: LP판 위를 바늘이 움직이듯, 데이터를 읽고 쓰는 헤드.

Detailed Explanation of Platter


성능을 결정하는 3요소

HDD의 속도가 느린 이유는 물리적인 움직임이 필요하기 때문이다. 데이터에 접근하는 시간($T_{access}$)은 다음 세 가지의 합이다.

  1. Seek Time ($T_{seek}$): 헤드가 원하는 트랙(실린더)으로 이동하는 시간. (가장 오래 걸림, 약 3~9ms)

  2. Rotational Latency ($T_{rotation}$): 플래터가 회전해서 원하는 섹터가 헤드 밑으로 올 때까지 기다리는 시간. (7200 RPM 기준 약 4ms)

  3. Transfer Time ($T_{transfer}$): 실제 데이터를 읽어 들이는 시간. (순식간임)

$$T_{access} = T_{seek} + T_{rotation} + T_{transfer}$$

결국 디스크 성능의 병목은 Seek TimeRotational Latency에 있다.



4. Disk Scheduling

느려터진 기계 장치(HDD Arm)가 더 부지런히 움직이게 하려면 어떻게 해야 할까? OS는 디스크 I/O 요청을 큐(Queue)에 쌓아두고, 가장 효율적인 순서대로 처리하는 Disk Scheduling을 수행한다. 핵심은 "Seek Time 줄이기"다.

(1) FCFS (First-Come, First-Served)

  • 방식: 먼저 온 요청을 먼저 처리한다.

  • 평가: 구현은 쉽지만, 헤드가 디스크의 끝과 끝을 왔다 갔다 할 수 있다. 아래 예시에서는 총 헤드 이동 거리가 640에 달한다.

FCFS

(2) SSTF (Shortest Seek Time First)

  • 방식: 현재 헤드 위치에서 가장 가까운 트랙의 요청부터 처리한다. (Greedy Algorithm)

  • 평가: 이동 거리가 획기적으로 줄어든다 (예시 기준 236). 하지만 치명적인 단점이 있다. 바로 기아 상태(Starvation)다. 헤드 주변에 요청이 계속 들어오면, 멀리 떨어진 요청은 영원히 처리되지 못할 수도 있다. (CPU scheduling의 SJF와 유사!)

SSTF

(3) SCAN (Elevator Algorithm)

  • 방식: 엘리베이터처럼 한쪽 끝에서 다른 쪽 끝까지 훑으며 요청을 처리하고, 다시 반대 방향으로 훑는다.

  • 평가: Starvation 문제를 해결한다. 하지만 양 끝단보다 중간 트랙이 더 자주 방문 되는 불균형이 존재한다.

SCAN

(4) C-SCAN (Circular SCAN)

  • 방식: 한쪽 방향으로만 스캔하고, 끝에 도달하면 처리 없이 바로 시작점으로 돌아와 다시 스캔한다.

  • 평가: 모든 트랙에 대해 균일한 대기 시간을 보장한다.

C-SCAN

결론적으로 일반적인 부하에서는 SSTF가 빠르지만, 시스템 부하가 높을 때(Heavy load)는 공정성을 위해 SCAN이나 C-SCAN이 더 적합하다는 것을 알 수 있었다.



5. RAID: 신뢰성과 성능, 두 마리 토끼를 잡다

디스크 하나는 느리고, 고장 나기 쉽다. 그렇다면 "여러 개의 싸구려 디스크를 묶어서 크고 빠르고 안전한 하나의 디스크처럼 보이게 만들면 어떨까?" 이 아이디어가 바로 RAID(Redundant Array of Inexpensive Disks)다.

RAID는 OS에게 단일 디스크처럼 보이지만(Abstraction), 내부적으로는 성능과 신뢰성을 위한 치열한 설계가 숨어있다.

RAID

(1) RAID 0 (Striping): 속도의 극한

  • 구조: 데이터를 여러 디스크에 쪼개서(Striping) 저장한다. Parity(오류 검출용 데이터)는 없다.

  • 장점: 읽기/쓰기 속도가 디스크 개수(N)만큼 빨라진다. 공간 효율성도 100%다.

  • 치명적 단점: 디스크 중 하나만 고장 나도 전체 데이터가 날아간다. 신뢰성이 매우 낮다. (중요한 데이터 저장 금지!)

RAID 0

(2) RAID 1 (Mirroring): 안전 제일

  • 구조: 데이터를 똑같이 복사해서 두 군데(Mirror)에 저장한다.

  • 장점: 하나가 고장 나도 끄떡없다. 읽기 성능도 2배다.

  • 단점: 공간 효율성이 최악이다(50%). 비싼 디스크를 사서 반밖에 못 쓰는 셈이다.

RAID 1

(3) RAID 4 & RAID 5: 패리티(Parity)의 마법

공간 낭비 없이 신뢰성을 확보하기 위해 '패리티 비트'를 사용한다. XOR 연산을 이용하면 데이터가 손실되어도 복구할 수 있다.

Parity Blocks

  • RAID 4: 패리티를 전담하는 디스크를 따로 둔다. 읽기는 빠르지만, 데이터를 쓸 때마다 패리티 디스크도 업데이트해야 하므로 병목(Bottleneck)이 생긴다.

RAID 4

  • RAID 5: 패리티 블록을 모든 디스크에 분산 저장한다. RAID 4의 병목 문제를 해결한 방식으로, 랜덤 쓰기 성능이 더 좋다. (가장 밸런스가 좋은 방식)

RAID 5

(4) RAID 6: 엔터프라이즈의 표준

  • 구조: RAID 5에 패리티를 하나 더 추가했다(Dual Parity).

  • 특징: 디스크 2개가 동시에 고장 나도 데이터를 살릴 수 있다. 패리티 계산 오버헤드로 쓰기 속도는 약간 느리지만, 데이터 센터 등 중요 시스템에서 가장 선호된다.

RAID 6

6. 마치며

I/O 시스템부터 HDD, 그리고 RAID까지 학습하면서 느낀 점은 "완벽한 단일 하드웨어는 없다"는 것이다. HDD는 필연적으로 느리고 고장이 난다. 하지만 컴퓨터 공학은 이를 단순히 더 빠른 모터를 다는 방식(하드웨어 개선)으로만 해결하지 않았다.

  1. 계층 구조를 통해 비용 효율을 찾고,

  2. 스케줄링 알고리즘으로 물리적 이동을 최소화하며,

  3. RAID를 통해 여러 개의 불안전한 부품을 하나의 신뢰성 있는 시스템으로 재탄생시켰다.

결국 시스템 엔지니어링이란, 주어진 자원의 불완전함을 인정하고, 이를 아키텍처와 알고리즘으로 극복해 나가는 과정이다. 다음 시간에는 SSD에 대해 알아보고자 한다!




추천글:

[운영체제] Operating System 전체 포스팅 모음집

[운영체제] 페이징(Paging) | Page Table, Copy-on-Write, TLB

[운영체제] 스와핑(Swapping) | 물리 메모리의 한계를 넘어서는 기술

[시스템프로그래밍] Memory Hierachy - RAM / Disk mechanism, Locality, Caching



hyeon_B

안녕하세요! AI 기술을 이용해 더 나은 세상을 만들어 나가고 싶은 과기원생 Hyeon이라고 합니다. 저는 앞으로 인공지능 시대에는 지식을 '활용'하는 능력이 중요해질 것이라고 생각합니다. 대부분의 일들은 인공지능이 뛰어난 모습을 보이지만, 인공지능은 데이터로 부터 연관관계를 학습하기 때문에 지식들을 새로 통합해서 활용하는 능력이 부족합니다. 인공지능이 뉴턴 전에 만들어졌다면 사과가 떨어지는 이유에 대답하지 못했을 것이고, 아인슈타인 전에 만들어졌다면 중력이 어떻게 생기는지 설명하지 못했을 것입니다. 따라서 앞으로 우리는 '본질'을 탐구하고 그 본질로부터 다른 곳에 적용하며 인공지능을 현명하게 활용해야 할 것입니다. 함께 인공지능 시대를 준비합시다!

댓글 쓰기

다음 이전

POST ADS1

POST ADS 2