[운영체제][저장장치관리] 저장장치와 입출력(Storage & Input/Output) #2 입출력 시스템

2022. 7. 28. 12:15OperatingSystem

1. 입출력 시스템

컴퓨터의 두가지 주요한 일은 입출력(Input/Output)과 계산입니다. 하지만 컴퓨터는 대부분의 경우에 웹 브라우저, 파일 편집, 유튜브, 게임 등을 위한 입출력에 업무를 하고 있습니다. 입출력에서 운영체제의 역할은 입출력 연산과 기기들을 제어하고 관리하는 것입니다.

 

다음 그림은 입출력 버스의 구조를 나타냅니다.

위 그림을 보면 각각의 입출력 기기에는 기기를 제어하는 컨트롤러가 있는 것을 알 수 있고 명령어와 데이터가 버스를 통해서 이동되는 것을 알 수 있습니다.

 

2. Memory Mapped I/O

CPU는 입출력을 수행하기 위해서 컨트롤러에게 데이터와 명령을 어떻게 전달하는가?

컨트롤러는 데이터를 위한 다수의 신호 레지스터를 가지고 있기 때문에 이 레지스터들을 이용하여 데이터와 명령을 전달합니다.

  • data-in 레지스터   : 입력하기 위해서 호스트에 의해 읽혀집니다.
  • data-out 레지스터 : 출력을 하기 위해서 호스트에 의해서 작성됩니다.
  • status 레지스터     : 호스트에 의해서 읽혀질수 있는 비트를 포함합니다.
  • control 레지스터    :  기기의 모드를 변경하거나 명령어를 시작시키기 위해서 호스트에 의해서 작성될 수 있습니다.

 

CPU는 다양한 메모리 및 입출력 장치와 통신해야 하므로 프소세서와 입출력 장치 사이의 데이터는 시스템 버스의 도움을 받아 수행합니다. 시스템 버스를 할당받을 수 있는 방법 3가지는 다음과 같습니다.

  1. 입출력과 메모리에 대한 제어신호, 주소, 데이터 버스를 분리하는 방법 (Isolated I/O)
  2. 입출력과 메모리가 제어 신호 버스는 따로 두되 데이터와 주소에 대한 공통 버스를 가지는 방법
  3. 입출력 및 메모리가 공통 버스(데이터, 주소 및 제어)를 가지는 방법 (Memory Mapped I/O)

2.1 Isolated I/O

첫번째 케이스의 경우 둘다 주소 공간과 명령어 집합이 다르지만 더 많은 버스가 필요하기 때문에 간단합니다. 그런 다음 입출력과 메모리를 위한 공통 버스(데이터 및 주소)가 있지만 입출력에 대한 읽기 및 쓰기 제어선은 별도로 구분되는 격리 입출력(Isolated I/O)가 있습니다. 따라서 CPU 디코딩 명령이 있을 때 데이터가 입출력용이라면 주소를 주소 라인에 배치하고 CPU와 입출력간에 데이터 전송이 발생하는 경우에는 입출력 읽기 또는 제어 라인에 설정합니다. 여기서 입출력의 주소를 포트(Port)라고 합니다. 여기서는 입출력과 메모리 모두에 대해 서로 다른 읽기-쓰기 명령어를 제공합니다.

 

2.2 Memory Mapped I/O

이 케이스는 동일한 명령어 집합이 메모리에 입출력에 대해서 작동하는 공통 버스입니다. 따라서 메모리와 마찬가지로 입출력을 조작하고 둘다 동일한 주소 공간을 가지고 있으며, 이로 인해 메모리 공간의 일부가 입출력에 의해 차지하기 때문에 메모리의 주소 지정 기능이 저하됩니다. 

 

2.3 Isolated I/O와 Memory Mapped I/O 비교

Isolated I/O Memory Mapped I/O
메모리와 입출력은 다른 주소 공간을 가지고 있음 메모리와 입출력은 같은 주소 공간을 가지고 있음
모든 주소들이 메모리에 의해서 사용될 수 있음 입출력이 메모리 공간에 추가되어 메모리 용량이 감소함
메모리와 입출력이 다른 읽기-쓰기 제어라인을 가짐 메모리와 입출력이 같은 명령어 제어 라인을 가짐
버스를 분리하기 때문에 더욱 효율적임 버스가 공통이기 때문에 효율적이지 않음
버스가 많아지기 때문에 크기가 더욱 큼 버스가 공통이기 때문에 크기가 작음
메모리와 입출력 모두를 제어하기 위해 별도의 로직이 사용되기 때문에 복잡함 입출력 또한 메모리로 취급되기 때문에 로직이 간단함

 

3. 입출력의 3가지 유형

  1. Polling(Busy-Waiting)
    • 사용중인 비트(bit)가 지워질때까지 상태 레지스터(status register)를 반복해서 읽는 것
  2. Interrupt
    • CPU는 인터럽트-요청 라인(interrupt-request line)이라고 불리는 선을 가지고 있습니다.
    • 만약 CPU가 인터럽트를 탐색한다면 인터럽트를 다루는 ISR(Interrupt Service Routine)으로 넘어갑니다.
    • ISR 주소 공간에는 인터럽트 벡터 테이블(Interrupt Vector Table)이 명세되어 있습니다.
    • 인터럽트 벡터 테이블은 컴퓨터에서 발생하는 인터럽트의 종류를 명세한 테이블입니다.
  3. DMA(Direct Memory Access)
    • 특정 하드웨어 하위 시스템이 CPU와 독립적으로 메인 시스템 메모리에 접근할 수 있게 해주는 컴퓨터 시스템의 기능입니다.
    • DMA는 큰 데이터 전송을 다루는데 유용합니다.

 

다음은 입출력 싸이클에서 인터럽트를 다루는 수행과정입니다.

  1. CPU에서 디바이스 드라이버가 입출력 초기화
  2. 입출력 컨트롤러가 입출력을 초기화
  3. 입력 대기, 출력 완료 또는 에러 발생 등을 이유로 인터럽트 신호를 생성합니다.
  4. CPU는 인터럽트 신호를 탐색하게 되고 인터럽트 핸들러에게 신호를 전송합니다.
  5. 인터럽트 핸들러는 인터럽트를 처리합니다.
  6. CPU는 수행을 재개합니다.
  7. CPU에서 디바이스 드라이버가 다시 입출력을 초기화합니다.

 

다음 그림은 인터럽트 벡터 테이블입니다.

위의 테이블을 보면 대표적인 인터럽트에는 수를 0으로 나누는 경우에 0번 인터럽트가 존재합니다.

 

다음 그림은 DMA 전송의 수행과정을 나타낸 것입니다.

  1. 디바이스 드라이버는 드라이브2의 데이터를 메모리의 주소 "x"의 버퍼로 전송하라는 지시를 받습니다.
  2. 디바이스 드라이버는 드라이브 컨트롤러에게 메모리의 주소 "x"의 버퍼에 "c" byte 단위로 전송하라고 말합니다.
  3. 디바이스 컨트롤러는 DMA 전송을 초기화합니다.
  4. DMA 컨트롤러는 메모리의 주소 "x" 버퍼에 데이터를 전송합니다.
  5. DMA는 CPU에게 전송 완료 신호 인터럽트를 전달합니다.

 

4. Blocking I/O vs Non-blocking I/O

  • Blocking I/O : Blocking I/O 방식으로 수행하면 쓰레드가 중지되고 쓰레드가 실행큐에서 대기큐로 이동됩니다.
  • Non-blocking I/O : Non-blocking I/O 방식으로 수행하면 쓰레드의 실행이 중지되지 않습니다.
    • 예를 들어 워드프로세서에서 키보드 또는 마우스의 입력이 해당됩니다.
  • Asynchronous system call : 이 방식또한 쓰레드가 계속 실행됩니다.

 

4.1 Non-blocking I/O와 Asynchronous system call 비교

Non-blocking I/O

non-blocking read() 함수를 호출하면 사용가능한 데이터가 무엇이든 즉시 리턴(리턴 값은 요청받은 바이트 전체가 될수도 있고 혹은 그보다 적거나 또는 아예 없을 수도 있음)받게 됩니다.

 

예를 들어 네트워크 소켓에서 사용하는 select() 시스템 콜이 있습니다. 이 시스템 콜은 최대 대기 시간 정보를 인자로 갖고 있습니다. 이 값을 0으로 설정하게 되면 쓰레드는 blocking 없이 네트워크 활동에 대해서 주기적으로 확인합니다. 하지만 select() 함수를 사용하게 되면 추가적인 오버헤드가 발생하게 되는데 이는 select()는 오직 입출력이 가능한지 여부만을 확인(실제 데이터 전송은 일어나지 않음)하기 때문입니다. 데이터 전송을 위해서는 select() 이후에 read()나 write() 호출이 반드시 수반되어야 합니다.

 

Asynchronous system call

asynchronous system call read() 함수를 호출하면 이 함수 전체에 걸쳐 수행될 예정이나 나중에 완료될 전송을 요청합니다.

 

다음 그림은 synchronous와 asynchronous의 수행방식을 비교한 그림입니다.

위 그림을 보면 synchronous 수행 방식은 입출력이 발생하면 완료될때까지 대기하는데 반해 asynchronous 수행 방식은 입출력이 발생하면 수행을 걸어두고 프로세스를 수행하는 것을 볼 수 있습니다.

 

 

References

source code : https://github.com/yonghwankim-dev/OperatingSystem_Study
Operating System Concepts, 10th Ed. feat. by Silberschatz et al.
[인프런] 운영체제 공룡책 강의
Blocking, Nonblocking, Sync, Async를 이해해보자
직접 메모리 접근
Memory mapped I/O and Isolated I/O