입출력장치는 CPU, 메모리보다 다루기 까다롭다. 그 이유는 다음과 같다.
전송률(transfer rate)
: 데이터를 얼마나 빨리 교환할 수 있는지를 나타내는 지표위와 같은 이유로 입출력장치는 컴퓨터에 직접 연결되지 않고 장치 컨트롤러(device controller)
라는 하드웨어를 통해 연결된다. 장치 컨트롤러는 입출력 제어기(I/O controller)
, 입출력 모듈(I/O module)
등으로도 불린다.
모든 입출력장치는 각자의 장치 컨트롤러를 통해 컴퓨터 내부와 정보를 주고받고, 장치 컨트롤러는 하나 이상의 입출력장치와 연결되어 있다.
장치 컨트롤러는 다음과 같은 역할을 통해 앞에서 언급한 문제들을 해결한다.
버퍼링(buffering)
: 전송률이 높은 장치와 낮은 장치 사이에 주고받는 데이터를 버퍼(buffer)
라는 임시 공간에 저장하여 전송률을 비슷하게 맞추는 방법데이터 레지스터(data register)
상태 레지스터(status register)
제어 레지스터(control register)
장치 드라이버(device driver)
프로그램 입출력(programmed I/O)
: 프로그램 속 명령어로 입출력장치를 제어하는 방법CPU가 프로그램 속 명령어를 실행하는 과정에서 입출력 명령어를 만나면 CPU는 입출력장치에 연결된 장치 컨트롤러와 상호작용하며 입출력 작업을 수행한다.
CPU가 장치 컨트롤러에 내리는 명령어를 표현하고 메모리에 저장하는 방법은 두 가지가 있다.
메모리 맵 입출력(memory-mapped I/O)
고립형 입출력(isolated I/O)
인터럽트 기반 입출력(Interrupt-Driven I/O)
: 인터럽트를 기반으로 하는 입출력입출력장치에 의한 하드웨어 인터럽트는 입출력장치가 아닌 장치 컨트롤러에 의해 발생한다.
CPU는 장치 컨트롤러에 입출력 작업을 명령하고, 장치 컨트롤러가 입출력장치를 제어하며 입출력을 수행하는 동안 CPU는 다른 작업을 할 수 있다. 장치 컨트롤러가 입출력 작업을 끝낸 뒤 CPU에게 인터럽트 요청 신호를 보내면 CPU는 하던 일을 잠시 백업하고 ISR을 실행한다.
인터럽트가 발생한 순서대로 인터럽트를 처리할 때
=> 인터럽트 중에서도 더 빨리 처리해야 하는 인터럽트가 있기 때문에 현실적으로 어려움
즉, CPU는 인터럽트 간에 우선순위를 고려하여 우선순위가 높은 인터럽트 순으로 여러 인터럽트를 처리할 수 있다.
NMI(Non-Maskable Interrupt)
: 인터럽트 비트를 비활성화해도 무시할 수 없는 인터럽트프로그래머블 인터럽트 컨트롤러(PIC; Programmable Interrupt Controller)
프로그램 기반 입출력과 인터럽트 기반 입출력 모두 입출력장치와 메모리 간의 데이터 이동은 CPU가 주도하고, 이동하는 데이터도 반드시 CPU를 거친다.
=> CPU는 입출력장치를 위한 연산 때문에 시간을 뺏기게 된다.
DMA(Direct Memory Access)
DMA 컨트롤러
라는 하드웨어가 필요하다.CPU는 DMA 컨트롤러에게 입출력 작업 명령을 내리고, 인터럽트만 받으면 되기 때문에 작업 부담을 훨씬 줄일 수 있다. 즉, CPU는 오로지 입출력의 시작과 끝에만 관여하면 된다.
DMA 컨트롤러는 시스템 버스로 메모리에 직접 접근이 가능하지만, 시스템 버스는 동시 사용이 불가능하다. 이 때문에 DMA 컨트롤러는 CPU가 시스템 버스를 이용하지 않을 때마다 조금씩 시스템 버스를 이용하거나, CPU가 일시적으로 시스템 버스를 이용하지 않도록 허락을 구하고 시스템 버스를 집중적으로 이용한다. 이를 CPU 입장에서는 버스에 접근하는 주기를 도둑 맞는 것처럼 보여 사이클 스틸링(cycle stealing)
이라고 부른다.
DMA를 위해 시스템 버스를 너무 자주 사용하면 그만큼 CPU가 시스템 버스를 이용하지 못한다. 이 문제는 DMA 컨트롤러와 장치 컨트롤러들을 입출력 버스(input/output bus)
라는 별도의 버스에 연결하여 해결할 수 있다.
입출력 버스
를 사용하면 DMA 컨트롤러와 장치 컨트롤러가 서로 데이터를 전송할 때는 시스템 버스를 이용할 필요가 없으므로 시스템 버스의 사용 빈도를 줄일 수 있다.
현대 대부분 컴퓨터에는 입출력 버스가 있다. 즉, 대부분의 입출력장치(장치 컨트롤러)는 시스템 버스가 아닌 입출력 버스와 연결된다.
더욱 발전한 DMA, 입출력 채널
DMA를 통해 CPU의 부담이 많이 줄었지만, 여전히 입출력 명령어의 인출, 해석, 실행하는 역할은 상당 부분 CPU의 몫이었다. 최근에는 메모리에 직접 접근할 뿐만 아니라 입출력 명령어를 직접 인출, 해석, 실행까지 하는 일종의 입출력 전용 CPU가 만들어졌다. 이를
입출력 프로세서(IOP; Input/Output Processor)
혹은입출력 채널(Input/Output Channel)
이라고 부른다.실제로 일부 최신 입출력장치 내부에는 별도의 CPU가 포함되어 있다.
DMAC(DMA Controller)
의 경우 CPU는 모든 단일 IO 작업을 시작하는데 관여한다. DMA 방식은 Programmed I/O, 인터럽트 기반 I/O보다 우수하지만 CPU에서 간단한 시작 명령으로 전체 I/O를 처리하는 설계 방법이 있으면 전체 시스템 성능을 향상시킬 수 있다. IOP(I/O Processor)
설계는 이 요구 사항을 지원한다.
IOP는 I/O 작업의 DMA 개념을 확장한 것이다. IOP는 자체 메모리가 있으며 I/O 명령을 해석하고 실행할 수 있다. 이러한 명령어는 주기억장치에서 가져온다. 데이터 전송은 메모리를 통해 직접 발생한다. 즉, IOP는 CPU에서 최소한의 시작 명령만으로 IO 작업을 상당 부분 제어할 수 있다.