포스트

입출력 장치

입출력 장치

입출력 장치와 I/O 모듈

입출력 장치(I/O Device) 는 컴퓨터가 외부와 상호작용하기 위한 모든 하드웨어를 의미합니다. 키보드, 마우스처럼 데이터를 입력받는 장치와 모니터, 프린터처럼 데이터를 출력하는 장치, 그리고 네트워크 카드처럼 입출력을 모두 수행하는 장치로 나뉩니다.

이러한 장치들은 종류가 너무 다양하고, CPU에 비해 처리 속도가 매우 느리며, 사용하는 데이터 형식도 제각각입니다. CPU가 이 모든 장치를 직접 제어하는 것은 극심한 비효율을 초래합니다.

이 문제를 해결하기 위해 I/O 모듈(I/O Module) 또는 장치 컨트롤러(Device Controller) 가 존재합니다.

입출력 모듈

입출력 장치는 컴퓨터 내부의 CPU와 주기억 장치보다 속도가 매우 느려서 직접 통신이 불가능해 입출력 모듈이 이들 중간에서 데이터 흐름을 중재합니다. (자체 버퍼를 사용하여 일시적으로 데이터를 저장)

  • 인터페이스 제공 : CPU와 입출력 장치를 물리적/논리적으로 연결합니다.
  • 데이터 버퍼링(Buffering) : CPU와 입출력 장치 간의 속도 차이를 완화하기 위해 데이터를 임시로 저장하는 버퍼(Buffer) 를 가집니다.
  • 오류 검출 : 데이터 전송 중 발생할 수 있는 오류를 감지합니다.
  • 제어 및 타이밍 조절 : CPU의 명령을 해석하여 실제 장치를 제어하고, 데이터 전송 타이밍을 맞춥니다.

I/O 주소 지정 방식

CPU가 I/O 모듈과 통신하기 위해 모듈 내의 레지스터에 접근하는 방식은 크게 두 가지로 나뉩니다.

  • 메모리 맵 입출력 (Memory-Mapped I/O, MMIO) : I/O 모듈의 레지스터들을 메모리 주소 공간의 일부로 할당하는 방식입니다. CPU는 I/O 레지스터를 일반 메모리에 접근하는 것과 동일한 명령어(예: MOVE, LOAD) 를 사용하여 접근합니다. 구조가 단순해지고 다양한 메모리 관련 명령어를 I/O에 활용할 수 있어, ARM 프로세서 등 많은 최신 시스템에서 사용하는 방식입니다.
  • 포트 맵 입출력 (Port-Mapped I/O 또는 Isolated I/O) : 메모리 주소 공간과 별도의 I/O 포트 주소 공간을 사용하는 방식입니다. CPU는 IN, OUT과 같은 I/O 전용 명령어를 사용해야만 I/O 모듈에 접근할 수 있습니다. 메모리와 I/O 공간이 분리되어 프로그래밍이 명확해지는 장점이 있으며, Intel x86 계열 프로세서에서 전통적으로 사용해온 방식입니다.

CPU는 특정 장치에 직접 명령하는 대신, 해당 장치의 I/O 모듈에 간단한 명령(데이터 읽기 등)을 내리고, 복잡한 제어는 I/O 모듈이 알아서 처리합니다.

다양한 입출력 제어 기법

CPU가 I/O 모듈과 데이터를 주고받는 방식(I/O 제어 기법)은 컴퓨터의 효율성을 결정하는 중요한 요소입니다. 이 기법은 CPU의 개입 정도에 따라 발전해왔습니다

프로그램 입출력(Programmed I/O, PIO)

CPU가 직접 I/O 작업의 모든 과정을 제어하는 가장 간단한 방식입니다.

  1. CPU는 I/O 모듈에 ‘데이터 준비’ 명령을 보냅니다.
  2. CPU는 I/O 모듈의 상태 레지스터를 주기적으로 계속 확인(폴링, Polling) 하며 데이터가 준비되었는지 물어봅니다.
  3. 데이터가 준비되면, CPU가 직접 데이터를 I/O 모듈의 버퍼에서 자신의 레지스터로 가져옵니다.

CPU가 데이터가 준비될 때까지 무한정 대기하며 다른 일을 전혀 하지 못합니다 (Busy-Waiting). CPU 시간을 극심하게 낭비하여 현대적인 시스템에서는 거의 사용되지 않습니다.

인터럽트 입출력(Interrupt-driven I/O)

프로그램 I/O의 비효율적인 폴링(Polling)을 제거한 방식입니다.

  1. CPU는 I/O 모듈에 ‘데이터 준비’ 명령을 보낸 후, 다른 작업을 계속 수행합니다.
  2. I/O 모듈은 데이터 준비가 끝나면 CPU에 인터럽트(Interrupt) 신호를 보냅니다.
  3. 인터럽트를 받은 CPU는 하던 일을 잠시 멈추고, I/O 모듈로부터 데이터를 가져옵니다.
  4. 데이터 전송이 끝나면 중단했던 작업으로 복귀합니다.

CPU가 대기 시간 없이 다른 유용한 작업을 할 수 있어 CPU 활용률이 크게 향상되지만, 여전히 데이터 전송 자체는 CPU가 직접 수행해야 합니다. 따라서 대량의 데이터를 전송할 경우, 잦은 인터럽트와 데이터 이동으로 인해 CPU에 상당한 부담이 됩니다.

직접 메모리 접근 (Direct Memory Access, DMA)

CPU의 개입을 최소화하여 I/O 모듈이 직접 메모리에 접근해 데이터를 전송하는 가장 진보된 방식입니다. 이 방식을 위해 DMA 컨트롤러라는 특수한 I/O 모듈이 필요합니다.

  1. CPU는 DMA 컨트롤러에 명령을 한 번만 내립니다. (메모리 1000번지부터 1MB 크기의 데이터를 디스크 500번 섹터로 옮기기 등)
  2. CPU는 명령을 내린 후 즉시 다른 작업을 수행합니다.
  3. DMA 컨트롤러가 CPU 대신 시스템 버스를 제어하여 I/O 장치와 주기억장치 간의 데이터 전송을 직접 수행합니다.
  4. 지정된 데이터 전송이 모두 완료되면, DMA 컨트롤러는 CPU에 인터럽트 신호를 딱 한 번 보냅니다.

데이터 전송에 CPU가 전혀 관여하지 않으므로 CPU의 부담을 획기적으로 줄여줍니다. 대용량 데이터 전송(디스크 I/O, 네트워크 통신 등)에 매우 효율적이며, 현대 컴퓨터 시스템의 표준 방식입니다.

현대의 DMA 컨트롤러는 여러 개의 채널(Channel)을 가지고 있어, 동시에 여러 입출력 장치의 데이터 전송을 독립적으로 처리할 수 있습니다. 각 채널은 특정 입출력 장치에 할당되어 자신만의 전송 요청을 관리합니다. 예를 들어, 한 채널이 디스크에서 메모리로 데이터를 옮기는 동안 다른 채널은 네트워크 카드에서 들어온 데이터를 메모리로 옮길 수 있어 시스템의 전반적인 I/O 처리량을 높입니다.

사이클 스틸링(Cycle Stealing) : DMA 컨트롤러가 데이터 전송을 위해 시스템 버스를 사용할 때, CPU도 동시에 버스를 사용해야 할 수 있습니다. 이때 DMA 컨트롤러가 잠시 CPU로부터 버스 제어권을 ‘훔쳐’ 사용하는데, 이를 사이클 스틸링이라고 합니다.

운영체제와 입출력

지금까지 설명한 모든 입출력 제어 과정은 하드웨어 단독으로 이루어지지 않으며, 운영체제(OS)의 커널에 의해 긴밀하게 관리됩니다. 응용 프로그램이 입출력 요청을 하면, 운영체제는 해당 장치를 제어하는 소프트웨어인 장치 드라이버(Device Driver) 를 통해 I/O 모듈에 명령을 전달합니다.

즉, 장치 드라이버는 하드웨어(I/O 모듈)와 소프트웨어(OS) 사이의 인터페이스 역할을 하며, 복잡한 입출력 제어 과정을 추상화하여 응용 프로그램이 하드웨어를 쉽게 사용할 수 있도록 돕습니다.

이 기사는 저작권자의 CC BY-NC 4.0 라이센스를 따릅니다.