여태까지 연산, 저장 장치들에 대해 알아보았다. 이러한 장치들은 대부분의 컴퓨터에 공통적으로 포함되어있다. 그렇다면 컴퓨터마다 다른 종류를 가지고 있는 장치들은 무엇이고, 컴퓨터는 이들을 어떤 방식으로 처리하고 있을까? 이들에 대해 알아보자.
컴퓨터는 컴퓨터마다 다른 입출력장치를 가지고 있다. 입출력장치는 컴퓨터 내부와 외부 간 통신을 할 수 있는 장치이다. 모니터, 키보드, 마우스 스피커 등 다양한 장치들이 존재하며 보조기억장치도 포함되기도 한다.
이러한 다양한 장치들이 컴퓨터 내부와 연결하기 위해선 장치 컨트롤러와 장치 드라이버가 필요하다.
(장치 컨트롤러의 모습)
장치 컨트롤러는 입출력 장치와 CPU 사이에 존재하는 하드웨어이다. 장치 컨트롤러는 1. 입출력장치의 많은 종류를 CPU에 상호작용할 수 있도록 하고 2. CPU와 입출력 장치 간의 전송률 차이를 완화하는 역할을 한다.
장치 컨트롤러는 CPU와 입출력 장치 사이에서 통신을 중개한다. 이를 통해 CPU가 다양한 입출력 장치가 아닌 하나의 장치 컨트롤러만 알고있으면 되도록 하였다. 여기에 더해, 중개 과정속에서 입출력 장치의 오류 또한 검출하기도 하며, 데이터를 버퍼를 이용하여 전송률 차이를 완화한다.
버퍼는 대량의 데이터를 모은 후 소량씩 여러 번 내보내거나, 소량의 데이터를 모은 후 대량으로 내보낼 수 있다. 전송률이 높은 CPU에서 들어온 대량의 데이터는 입출력 장치에게 소량으로 여러 번 입출력 장치에게 내보내고, 전송률이 낮은 입출력 장치에서 들어온 소량의 데이티는 모았다가 대량으로 CPU에게 내보내어 전송률 차이를 완화한다.
장치 컨트롤러는 데이터 레지스터, 상태 레지스터, 제어 레지스터로 구성되어 있다.
(장치 드라이버 - 장치 컨트롤러 - 입출력장치의 구성)
장치 컨트롤러가 하드웨어적인 구성요소라면, 장치 드라이버는 소프트웨어적인 구성요소이다. 장치 컨트롤러가 CPU와 상호작용을 할 수 있도록 하는 프로그램이다.
일반적으로 운영체제에 의해 제공되며, 일부 입출력 장치의 장치 드라이버는 제조사에서 직접 제공하기도 한다.
장치 드라이버에 의해 CPU와 장치 컨트롤러가 상호작용을 한다고 배웠다. 이번에는 이러한 상호작용이 일어나는 방법 3가지에 대해 알아보자.
프로그램 입출력 방법은 명령어로 입출력장치를 제어하는 방법이다. CPU가 입출력 명령어를 제어 컨트롤러에게 내려 진행된다.
데이터를 보조기억장치(입출력 장치)에 저장하는 예시를 통해 살펴보자.
이 때, CPU가 장치 컨트롤러의 레지스터들을 인식하는 방법은 2가지가 있다.
메모리 주소 공간을 메모리를 위한 공간과 입출력 장치에 접근하기 위한 공간으로 나누어 간주하는 방법이다. 메모리를 위한 명령어로 입출력 명령까지 처리할 수 있어 간단한 명령 구조를 사용한다. 하지만, 메모리와 같은 버스를 사용하기에 (버스는 동시에 사용할 수 없다.) 성능에 악영향이 있을 수 있다.
메모리 주소 공간과 입출력 장치의 주소 공간을 분리하는 방법이다. 다른 주소 공간 & 버스를 사용하기에 속도도 빠르며, 공간 효율도 뛰어나다. 포트 맵 입출력이라고도 불린다.
CPU가 장치 컨트롤러의 상태 레지스터를 일일이 확인하지 않고, 제어 레지스터에 명령만을 내린 후, 장치 컨트롤러에서 작업이 완료된다면 인터럽트 요청을 날리는 방식이다. 장치 컨트롤러가 인터럽트를 날리기 전까지 CPU는 다른 작업을 할 수 있다.
(순차 처리되는 모습)
플래그 레지스터의 인터럽트 비트가 비활성화된 경우는 위와 같이 여러 인터럽트들을 순차적으로 처리한다.
(A 실행 도중에 B가 처리되는 모습)
인터럽트 비트가 활성화 되어 있고 새로 들어온 인터럽트가 우선순위가 높은 경우 혹은 새로 들어온 인터럽트가 NMI*인 경우는 위와 같이 기존 인터럽트를 멈추고 새로 들어온 인터럽트부터 처리할 수 있다. 첫 번째 경우는 PIC에 의해 처리된다.
(PIC의 모습)
PIC는 Pogrammable Interrupt Controller의 약자로 장치 컨트롤러로부터 여러 인터럽트 요청을 받아들인 후, 우선순위에 맞게 CPU에 인터럽트 요청 신호와 인터럽트 벡터를 보내는 역할을 한다. 이를 통해 많은 인터럽트를 관리할 수 있다. 수많은 장치들의 인터럽트를 관리하기 위해 계층적으로 구성하기도 한다.
*NMI(Non-Maskable Interrupt): 어떤 인터럽트보다 높은 우선순위를 가지고, 저지(mask)되지 않는 인터럽트이다.
CPU가 다른 작업에 집중할 수 있도록, CPU를 대신하여 메모리나 장치 컨트롤러와 상호작용하고 작업 완료시 CPU에 인터럽트 요청을 날리는 방식을 DMA 방식, 이 때 사용되는 물리적인 장치를 DMA 컨트롤러라고 한다.
동작 방식은 아래와 같다.
CPU를 대신하여 장치 컨트롤러와 상호작용하여 CPU에 부담을 줄여주려는 목적하에 등장하였지만 , 동시 사용이 불가능한 시스템 버스를 CPU와 같이 사용한다는 문제가 있다. 이는 최대한 CPU가 사용하지 않을 때 시스템 버스를 사용하거나, 일시적으로 허락을 구하고 시스템 버스를 사용하여 해소한다. 이러한 행위를 사이클 스틸링이라고 부른다.
장치 컨트롤러와의 상호작용도 시스템 버스에서 일어나기 때문에, 별도 버스인 입출력 버스를 이용하여 시스템 버스의 사용 빈도를 줄이기도 한다. 대부분의 현대 컴퓨터는 입출력 버스가 갖춰져 있고, 이러한 구성요소는 PCI 버스, PCIe 버스 등으로 불린다.
입출력 방식 선택 역시 상황마다 다르다. 하지만, 일반적으로 DMA를 사용하는 것이 효율적이라고 하며, 아주 작은 시스템에서는 프로그램 입출력방식도 고려한다고 한다.