CPU는 입출력 작업동안은 멈출 수 밖에 없으므로, 컴퓨터는 입출력 작업이 많으면 느려집니다. 특히나 비휘발성 메모리로부터의 입출력처럼 대량 데이터 이동일 때 오버헤드가 아주 커집니다. CPU는 계속 명령어에 의해 돌아가야 낭비가 없으므로, 이 문제를 해결하기 위해 DMA(직접 메모리 엑세스) 방식을 사용합니다.

 

이전까지 장치 컨트롤러가 메모리에 접근하기 위해서는 원하는 데이터에 접근하기위해 interrupt-driven방식을 통해 CPU에게 요청했습니다. interrupt방식은 HDD에서 RAM에 올리고, RAM에서 CPU에 올리고 하는 과정 하나하나 OS에다가 interrupt를 걸어야 합니다. 게다가 interrupt-driven 방식은 byte단위이므로, OS에게 매번 요청하다보면 오버헤드가 커질 수 있습니다.

 

반면 DMA방식은, CPU에 interrupt를 걸지 않고 직접적으로 메모리에 접근해서 읽어오는 방식입니다. 이를 위해 데이터를 byte 단위가 아닌 block 단위로 읽습니다. HDD에서부터 block 단위로 RAM에 올리고, RAM에서 CPU에 올릴 때도 block 단위로 올리게 됩니다. 

 

즉 DMA방식은 CPU의 개입 없이 메모리로부터 자신의 버퍼 장치로, 또는 버퍼로부터 메모리로 데이터 블록 전체를 전송합니다. DMA방식에서 interrupt는 블록 전송이 완료될 때마다 발생하게 되며, 장치 컨트롤러가 전송작업을 수행하는 동안 CPU는 다른 작업을 수행할 수도 있습니다.

 

---

다음 글에서는 컴퓨터 시스템의 구조에 대해 알아보겠습니다.

'OS 공룡책' 카테고리의 다른 글

저장장치 구조  (0) 2022.05.15
인터럽트  (0) 2022.05.14
운영체제의 정의  (0) 2022.05.14

저장장치는 크게 휘발성, 비휘발성 두가지 종류로 나눌 수 있고, 저장장치 구조에는 계층이 있습니다.

 

휘발성 저장장치(NVS)은 전기적 저장장치로, RAM, 캐시, 레지스터가 이에 속합니다.

비휘발성 저장장치(NVM)은 기계적 저장장치로, ROM, HDD, SSD, 자가 디스크, 광학 디스크, 자가 테이프가 이에 속합니다. 

 

저장장치 구조는 속도가 빠른 또는 비트당 비용이 작은 순서대로 나열하면 레지스터, 캐시메모리, 메인메모리, SSD, 자가디스크, 광학디스크, 자기테이프이며 저장용량이 큰 순서는 역순입니다. 이때 레지스터와 캐시 메모리는 CPU안에 위치합니다.

메모리 계층 구조

비교적 생소한 캐시의 기능에 대해 웹 캐싱을 빗대어 이해해보겠습니다. 특정한 페이지가 갑자기 유입이 많아졌다고 생치면, 기존에 검색엔진을 통해서만 열 수 있었던 사이트페이지를, 동일한 페이지 자체를 만들어서 캐시 서버에 넣어 둘 수 있습니다. 그렇게 함으로써 웹 브라우저들이 그 페이지로 유입할 때 검색엔진에 부하를 주지 않고 캐시 서버로 가서 페이지에 접속할 수 있습니다. 저장장치에서의 캐시도 마찬가지 입니다. 메인메모리는 레지스터에 내용을 올려서 CPU는 명령을 실행하게 되는데, 이때 메인메모리가 캐시에 내용을 올리고 캐시가 레지스터에 내용을 올려서 CPU가 명령을 실행하는 것이 레지스터에 바로 명령을 올리면서 명령을 실행할 때보다 빠를 수 있습니다. 왜냐하면 CPU는 코드를 보고 특정하게 많이 실행되는 부분(locality)을 판단해서 미리 메인메모리에서 캐시로 올려두는데(hit), 캐시에서 레지스터로 올리는건 아주 빠르기 때문입니다. 결국 캐시에 없는 부분만 메인메모리에서 레지스터로 올리면 되는 형태가 됩니다. 

 

※ 소스코드의 locality란? 소스코드에 많이 실행되는 특정 부분이 있음.

locality한 부분이 캐시에 잘 올라 갔으면 hit이라하고 아니면 miss라 합니다. miss라 해도 메인메모리에서 직접 레지스터에 등록할 것이므로 실행에는 문제가 없습니다.

 

---

다음 글에서는 입출력 구조에 대해 알아보겠습니다.

 

'OS 공룡책' 카테고리의 다른 글

입출력 구조  (0) 2022.05.15
인터럽트  (0) 2022.05.14
운영체제의 정의  (0) 2022.05.14

인터럽트 매커니즘은 컴퓨터를 설계하는가에 따라 상이할 수 있습니다. 일반적인 방법을 알아보겠습니다.

 

앞서 설명했듯 하드웨어는 '언제든지' 시스템 버스를 통해 신호를 보내 인터럽트를 발생시킬 수 있으므로, 인터럽트는 비동기 이벤트를 처리하는 방식입니다. 

 

인터럽트는 장치 컨트롤러의 요청에 의해서도 발생할 수 있지만, 하드웨어 오류로 인해 프로그램을 중지시키기 위해서도 인터럽트가 발생될 수 있습니다. 이때, 인터럽트는 "시스템 오류로 인해 프로그램이 중지됨을 알리기 위해" interrupt service routine을 통합니다. interrupt service routine을 통하지 않으면 영문도 모른 채 프로그램이 종료되는 것처럼 보일 것입니다.

 

인터럽트 서비스 루틴(interrupt service routine,ISR)은 인터럽트 고유 핸들러(interrupt handler)와 같은 말입니다. (교재에는 단어가 혼용되어 기술돼 있습니다. 익숙해지기 위해 아래에서 저도 혼용해서 사용하고 있습니다.)

---

인터럽트 벡터, 인터럽트 체인

 

아무튼 인터럽트 요청에 대해 OS는 ISR를 찾아서 호출해 주어야 합니다. 인터럽트는 매우 빈번하게 일어나는 요청이므로, OS는 요청에 대해 어떤 interrupt servie routine를 이용해서 해당 인터럽트를 처리할 것인지 “빨리 결정” 해야 합니다. 그러기 위해서 interrupt servie routine들에 대한 포인터들로 이루어진 테이블을 미리 만들어두고 접근하면 빠릅니다. 이것을 인터럽트 벡터 방식 이라고 합니다.

 

인터럽트 벡터는 인터럽트 핸들러 리스트의 헤드 주소들을 모아놓은 배열이며(인덱스로 사용해서 점프), 하위 메모리에 약 100개 정도 저장되어 있습니다. 따라서 인터럽트 벡터는 HW적인 방식입니다.

 

즉, 인터럽트 벡터 방식을 이용하면 필요한 장치를 결정하기 위해 하나의 인터럽트 핸들러가 가능한 모든 인터럽트 소스를 검색할 필요를 줄일 수 있습니다. 인터럽트 벡터 방식을 사용하지 않는다면 OS는 인터럽트 요청에 대해서 해당 인터럽트의 정보를 조사하기 위한 루틴을 호출한 뒤에 인터럽트 소스를 모두 검사한 뒤, 인터럽트 고유 핸들러를 호출 하는 직선적인 방법을 사용해야 합니다. 

 

인터럽트 벡터는 하위 메모리에 약 100개 정도 저장되어 있다고 언급했습니다. 그러나 실제 컴퓨터에는 인터럽트 벡터의 주소 개수보다 많은 장치가 있습니다. 이 문제를 해결하기 위해서 인터럽트가 일어날 수 있는 장치들을 한 개의 회선에 직접 직렬로 연결해 두는 방법이 있습니다. 이것을 인터럽트 체인(데이지 체인)이라고 합니다. 연결할 때 우선순위에 맞게 연결할 수 있습니다. 인터럽트가 발생하면 요청을 처리할 수 있는 핸들러를 발견할 때 까지 인터럽트 핸들러 리스트를 하나씩 호출합니다. 

 

---

CPU관점에서 인터럽트

 

CPU는 명령을 처리하는 곳입니다. CPU는 하나의 명령어를 실행완료할 때마다 인터럽트 요청 라인(Interrupt request line)을 감지하는데, 컨트롤러로부터의 인터럽트요청이 있으면 즉시 하던일을 멈추고 인터럽트 포인터가 가리키는 위치로 실행을 옮깁니다. 그리고 interrupt service routine(interrupt handler)이 완료되면 CPU로 돌아가서 복귀 주소를 프로그램 카운터(PC)에 적재하고 인터럽트된 시점에서 연산을 재개합니다.

 

CPU가 인터럽트 이후에도 인터럽트 이전에 하던 작업을 이어서 계속 해야하기 때문에, 인터럽트 루틴에서 현재 상태를 저장해야하고 복귀하기 전에 상태를 복원하는 작업이 필요합니다. 이 작업은 인터럽트 처리기가 합니다.

인터럽트 처리기는 작업 중 변경상태 저장, 인터럽트 원인 확인, 필요한 처리 수행, 상태 복원, CPU의 인터럽트 전 상태로 점프 합니다.

 

또, 가장 긴급한 작업을 먼저 수행하기 위해 최신 컴퓨터는 인터럽트 우선순위 시스템을 사용합니다. 우선순위 레벨을 통해 CPU는 모든 인터럽트를 마스킹하지 않고도 우선순위가 낮은 인터럽트 처리를 연기할 수 있으며, 우선순위가 높은 인터럽트가 실행을 선점할 수 있습니다. 인터럽트는 maskable과 unmaskable로 나뉘는데, unmaskable 인터럽트는 즉시 실행되어야 하는 인터럽트로,벡터번호 0~31번상에 있습니다. maskable 인터럽트는 비교적 후 순위로 벡터번호 32~255번 입니다.

 

인터럽트를 마무리하면서, CPU의 관점에서 인터럽트의 전체적인 흐름을 살펴보겠습니다.

1. 장치 컨트롤러가 인터럽트 요청 라인에 신호를 선언해서 인터럽트 발생

2. CPU가 인터럽트 포착 및 인터럽트 핸들러로 디스패치(인터럽트 번호를 인터럽트 벡터의 인덱스로 사용해서 인터럽트 핸들러 루틴으로 점프) 

3. 인터럽트 핸들러는 장치 서비스하고 인터럽트 지움

 

---

 

다음 글에서는 저장장치 구조, 입출력구조, 컴퓨터 시스템 구조에 대해서 알아보겠습니다.

'OS 공룡책' 카테고리의 다른 글

입출력 구조  (0) 2022.05.15
저장장치 구조  (0) 2022.05.15
운영체제의 정의  (0) 2022.05.14

컴퓨터 시스템은 HW(하드웨어), SW(소프트웨어), 그리고 데이터로 구성되어 있다고 볼 수 있습니다.

 

운영체제는 컴퓨터 시스템을 구성하는 요소들이 1. 컴퓨터의 자원들을 효율적으로 사용할 수 있도록 환경을 제공하며, 2.컴퓨터가 부적절하게 행동하지 않도록 프로그램을 컨트롤  하는 소프트웨어 입니다!

 

우리에게 익숙한 ios, window, linux 등 이 이런 역할을 한다는 것입니다. 그런데 상기처럼 한 문장으로 운영체제를 정의할 수는 없습니다. 운영체제는 워낙 복잡해서 아직까지도 운영체제란 무엇이다~ 하고 한마디로 정의하지 못합니다. 그렇지만 운영체제가 왜 존재하냐? 라고 한다면 "컴퓨팅 시스템이 만드는 문제를 유용하게 해결하는 방법을 제시하게 위해" 라고 말할 수 있습니다.

 

일반 사용자 관점에서는 운영체제가 컴퓨터 자원을 어떻게 쓰는지는 관심이 없습니다. 컴퓨터가 빠르고, 사용성이 좋으면 그만이지 내부적인 것까지 알 필요는 없으니까요. 우리는 앞으로 위에서 정의한 것처럼 시스템적 관점에서 운영체제가 어떻게 동작하는지 자세히 알아보겠습니다. 

 

---

시스템 관점에서 운영체제는

  • 효율적이고 공정하게 컴퓨터 시스템의 운영하게 합니다
  • cpu시간, 메모리 공간, 저장장치 공간, 입출력 장치와 같은 자원들을 관리합니다
    • 자원의 관리란 : 자원들의 상충될 수 있는 많은 요청들에게 어떤 자원을 얼마나 어떻게 할당하는지 결정하는 것
  • 즉, 효율적이고 공정하게 컴퓨터 시스템의 운영하게 합니다

---

 

컴퓨터는 CPU도, 마우스/키보드/프린터/모니터 같은 입출력 장치도, 하드디스크도 메모리를 통합니다. 장치들이 어떻게 작동할지 메모리를 통해서 CPU에게 명령을 내리고, CPU는 명령을 처리하고 장치들이 실제로 수행될 수 있게 하는 것입니다. 여러 장치들이 메모리와 연결되어야 하는데, 연결되는 길을 버스라고 합니다. 특히 여기서의 버스는(컴퓨터 시스템에는 많은 버스가 있습니다). 시스템 버스입니다. 

 

이때 장치는 직접 메모리와 연결되있지 않고, 장치-장치 컨트롤러-메모리 와 같은 모양입니다. 모든 장치에는 장치 컨트롤러가 있고, 운영체제는 각 장치 컨트롤러에 대응되는 장치 드라이버가 있습니다. 장치 컨트롤러는 HW이고, 장치 드라이버는 SW입니다. 그러니까 OS가 키보드와 같은 device를 바라볼때, 물리적으로 이 키보드가 어디서 만든 무슨 키보드인지는 관심이 없습니다. OS는 키보드를 논리적인 device, 즉 파일로써 본다. 이때 파일은 디바이스 컨트롤러라는 프로그램인 것입니다.

 

장치 컨트롤러-장치디바이스간에 상호작용은 이렇게 합니다 : 장치 드라이버는 장치 컨트롤러의 작동에 대해 알고 있으며, 이때 운영체제에는 일관된 인터페이스를 제공합니다. 장치 드라이버는 장치 컨트롤러 안의 적절한 레지스터에 값을 저장하고, 장치 컨트롤러는 레지스터의 내용을 검사한 뒤 작업을 결정해서 로컬 버퍼로 데이터를 보냅니다. 다 보냈으면 장치 드라이버에 알립니다. 

어떻게 알리느냐??? 장치 컨트롤러가 장치 드라이버에 작업을 알리는 방법을 인터럽트(interrupt)라고 합니다. 한편, OS가 버퍼의 내용들을 순서대로 읽는 SW적인 방식인 폴링(polling) 방식도 있는데 OS가 요청 순서대로 모두 살피기에는 안그래도 바쁘므로 잘 사용되지 않는다고 합니다. 폴링방식은 속도는 느리지만 회로가 간단하며 별도의 HW가 필요 없다는 장점이 있습니다.

 

OS의 장치드라이버가 받는 요청은 두 가지로 나눠서 바라볼 수 있습니다.

  • 장치드라이버가 받은 요청이 읽기 요청일 경우 : [ 데이터에 대한 포인터 ] or [ 데이터 자체 ] 를 반환한 뒤 운영체제
    다른 부분으로 제어를 넘깁니다.
  • 장치드라이버가 받은 요청이 읽기 요청이 아닌 경우 : [ 쓰기 완료 ] or [ 장치 사용 중 ] 과 같은 ‘상태 정보’를 반환합니다.

다음 글에서는 인터럽트가 무엇이고 어떻게 동작하는지 좀 더 알아보겠습니다.

---

 

 

 

 

'OS 공룡책' 카테고리의 다른 글

입출력 구조  (0) 2022.05.15
저장장치 구조  (0) 2022.05.15
인터럽트  (0) 2022.05.14

+ Recent posts