컴퓨터 구조의 문제점
컴퓨터 구조의 가장 큰 문제는 CPU와 메모리, 주변 장치 간 작업 속도가 다르다는 것이다. 메모리와 주변 장치는 시스템 버스(FSB)로 연결되어 있고, CPU(ALU, 제어 장치, 레지스터)는 CPU 내부 버스(BSB)로 연결되어 있다. 문제는 CPU 내부 버스의 속도가 시스템 버스의 속도보다 빠르기 때문에 메모리를 비롯한 주변 장치의 속도가 CPU의 속도를 따라가지 못한다. CPU에 비하면 메모리가 느리고 프로그램과 데이터를 보관하는 하드디스크는 메모리보다 느리다.
이런 문제로 장치간 속도를 개선하고 시스템 작업 속도를 올리기 위해 기술이 개발되었는데 버퍼, 캐시가 이에 해당된다.
버퍼(Buffer)
버퍼(Buffer)는 속도 차이가 있는 두 장치 사이에서 그 차이를 완화해준다. 예를 들어, 사과 50개를 마트에 옮긴다고 가정해보자. 한 번에 하나씩 옮기면 50번을 왕복해야 하지만 사과 50개를 트럭에 실어 옮기면 한 번에 옮길 수 있다. 이 때, 버퍼는 트럭에 비유된다.
입출력에서 데이터를 가져오는 경우에도 마찬가지이다. 느린 입출력 장치에서 데이터를 읽을 때마다 하나씩 전송하면 작업량에 비해 실제로 전송되는 데이터 양이 매우 작다. 따라서, 일정량의 데이터를 모아 전송하면 적은 노력으로도 많은 양의 데이터를 옮겨 속도의 차이를 완화할 수 있다.
또한, 버퍼는 소프트웨어적으로도 사용되는데 대표적인 예는 동영상 스트리밍이다. 동영상은 네트워크에서 데이터가 들어오는 시간과 플레이어가 재생되는 시간의 속도 차이가 발생한다. 플레이어가 재생되는 도중에 데이터가 도착하지 않으면 동영상이 끊기는데, 동영상 데이터 일정부분을 버퍼에 넣으면 이러한 현상을 방지해준다.
스풀(Spool)
스풀(Spool)은 CPU와 입출력장치가 독립적으로 동작하도록 고안된 소프트웨어적인 버퍼이다. 대표적으로는 프린터에 사용되는 스풀러(Spooler)이다. 스풀러는 인쇄할 내용을 순차적으로 출력하는 소프트웨어로 출력 명령을 내린 프로그램과 독립적으로 동작한다.
예를 들어, 워드프로세서로 작업을 하고 프린터로 출력할 때, 프린터 출력 작업과 문서 작업을 동시에 할 수 있는데 이는 스풀러를 사용했기 때문이다. 스풀러가 없다면 프린트 출력 작업과 문서 작업이 독립적으로 진행되지 못하기에 출력 작업이 끝날 때까지 문서작업을 할 수 없다.
또한, 스풀은 버퍼와 차이점이 있다. 버퍼는 어떤 프로그램이 사용하는 데이터든 버퍼가 차면 이동한다. 즉, 프로그램들 사이에 버퍼를 공유한다. 하지만, 스풀은 한 인쇄물이 완료될 때까지 다른 인쇄물이 끼어들 수 없다. 즉, 프로그램간에 배타적이다.
캐시(Cache)
캐시(Cache)는 메모리와 CPU 간의 속도 차이를 완화하기 위해 메모리의 데이터를 미리 가져와 저장해두는 임시 장소이다. 캐시는 필요한 데이터를 모아 한꺼번에 전달하는 버퍼의 일종으로 CPU가 앞으로 사용할 것이라고 예상되는 데이터를 미리 가져다 놓는다. 이 때, 미리 가져오는 작업을 미리 가져오기(prefetch)라고 한다. 예를 들면, 장독대에 있는 간장을 미리 간장통에 가져다 놓는 것을 들 수 있다.
캐시는 CPU 안에 있으며 CPU 내부 버스의 속도로 작동하기 때문에 느린 시스템 버스의 속도로 동작하는 메모리의 단점을 보완해준다.
캐시는 메모리 내용 중 일부를 미리 가져오고, CPU는 메모리에 접근해야 할 캐시를 먼저 방문해 원하는 데이터를 찾아본다. 만약 캐시에 데이터가 존재하면 캐시 히트(Cache hit)라고 하며 그 데이터를 사용한다. 하지만, 원하는 데이터가 없으면 메모리로 가서 데이터를 찾는데 이를 캐시 미스(Cache Miss)라고 한다. 캐시가 히트되는 적중률을 캐시 적중률(Cache hit ratio)라고 한다.
컴퓨터의 성능을 향상하려면 캐시 적중률이 높아야 한다. 캐시 적중률을 높이는 방법 중 하나는 캐시의 크기를 늘리는 것이다. 또한, 앞으로 많이 사용될 데이터를 가져오는 것이다. 현재 위치에 가까운 데이터가 멀리 있는 데이터보다 사용될 확률이 더 높다는 지역성(Locality) 이론이 있다.
캐시를 가져오는 것 뿐만 아니라 캐시에 있는 데이터가 변경되는 경우 이를 반영해야 하는 문제도 있다. 캐시는 메모리에 있는데이터를 임시로 가져온 것이기 때문에 캐리에 있는 데이터가 변경되면 메모리에 있는 원래 데이터를 변경해야 한다. 변경하는 방법에는 즉시 쓰기와 지연 쓰기 방식이 있다.
- 즉시 쓰기(Write through): 캐시에 있는 데이터가 변경되면 이를 즉시 메모리에 반영하는 방식, 메모리와의 빈번한 데이터 전송으로 인해 성능이 느려진다는 단점이 있지만, 급작스러운 정전에도 데이터를 잃지 않는다는 장점이 있다.
- 지연 쓰기(Write back): 변경된 내용을 주기적으로 반영하는 방식, 메모리와의 전송 횟수가 줄어 시스템의 성능을 향상할 수 있으나 메모리와 캐시된 데이터 사이의 불일치가 발생할 수 있다.
저장장치의 계층 구조
가격과 컴퓨터 성능 사이의 타협점으로 저장장치의 계층 구조(Storage hierarchy)가 존재한다. 저장장치의 계층 구조는 속도가 빠르고 값이 비싼 저장장치를 CPU 쪽에 두고, 값이 싸고 용량이 큰 저장 장치를 반대쪽에 배치하여 적당한 가격으로 빠른 속도와 큰 용량을 동시에 얻는 방법이다.
CPU와 가까운 쪽에 레지스터나 캐시를 배치하여 CPU가 작업을 빨리 진행할 수 있게한다. 비교적 속도가 느린 메모리에서 작업한 내용을 하드디스크와 같이 저렴하고 용량이 큰 저장장치에 영구적으로 저장한다. 이처럼 저장장치 계층 구조는 사용자가 저렴한 가격으로 용량은 하드디스크처럼 사용하고 작업 속도는 레지스터처럼 빠르도록 만들어 준다.
하지만 저장장치의 계층 구조는 중복되는 데이터의 일관성을 유지하는 것이 문제가 될 수 있다. 변경된 내용을 즉시 반영하지 않고 일정 기간 모았다가 한 꺼번에 메모리에 반영하는 지연 쓰기의 경우나 협업 중인 다른 작업에서 데이터를 읽으려 하거나 갑자기 전원이 꺼지는 경우가 해당한다.
인터럽트
컴퓨터에는 많은 주변장치가 있기 때문에 CPU가 모든 입출력에 관여하면 작업 효율이 현저하게 떨어진다. 이러한 문제를 해결하기 위해 등장한 것이 인터럽트(Interrupt) 방식이다. 인터럽트는 요리사 옆에 주방 보조를 두는 것과 같다. CPU 작업과 저장장치의 데이터 이동을 독립적으로 운영함으로써 시스템의 효율을 높인다. 즉, 데이터의 입출력이 이루어지는 동안 CPU는 다른 작업을 할 수 있다. 이 때, 입출력 관리자 또는 장치 관리자가 주방 보조에 해당한다.
[인터럽트 동작 방식]
- CPU가 입출력 관리자에게 입출력 명령을 보낸다.
- 입출력 관리자는 명령받은 데이터를 메모리에 가져다놓거나 메모리에 있는 데이터를 저장장치로 옮긴다.
- 데이터 전송이 완료되면 입출력 관리자는 완료 신호를 CPU로 보낸다.
이 때, 입출력 관리자가 CPU에게 보내는 완료 신호를 인터럽트라고 한다. CPU는 다른 작업을 하다가 완료 신호를 받으면 하던 작업을 중지하고 옮겨진 데이터를 처리한다. 인터럽트 방식에서는 많은 주변 장치중 어떤 것의 작업이 끝났는지를 CPU에 알려주기 위해 인터럽트 번호를 사용한다. 인터럽트 번호는 완료 신호를 보낼 때 장치의 이름 대신 사용하는 장치의 고유 번호로서 운영체제마다 다르다. 윈도우의 경우 인터럽트 번호를 IRQ(Interrupt ReQuest)라고 부른다.
CPU는 입출력 관리자에게 여러 개의 입출력 작업을 동시에 시킬 수 있다. 이 경우 여러 작업이 동시에 완료되고 그 때마다 인터럽트를 여러 번 사용해야 하는데 이는 비호율적이다. 그래서 여러 개의 인터럽트를 하나의 배열로 만든 인터럽트 벡터(Interrupt Vector)를 사용한다.
인터럽트 동작 방식은 다음과 같다. 입출력 요청 - 데이터 전송 - 인터럽트 발생 순으로 진행되는데 인터럽트 0번과 2번의 작업이 완료되어 인터럽트 0번과 2번이 동시에 발생했다는 것을 알 수 있다. CPU가 인터럽트 벡터를 받으면 0번과 2번의 작업을 동시에 처리한다.
입출력 작업을 알리는 인터럽트 외에도 다양한 종류의 인터럽트가 있는데 사용자가 컴퓨터의 전원 버튼을 눌러 강제 종료하면 CPU는 하던 일을 모두 멈추고 처리 중인 데이터를 안전하게 보관한 뒤 시스템을 종료해야 한다. 또한, 메모리에서 실행중인 어떤 작업이 자신에게 주어진 메모리 영역을 넘어서 작업을 하려 하거나 0으로 숫자를 나누면 인터럽트가 발생한다.
[참고]
- 직접 메모리 접근(Direct Memory Access, DMA): 메모리는 접근 권한을 가진 CPU만 접근이 가능하고 입출력 관리자는 접근이 불가능하다. 따라서, 입출력 관리자에게는 CPU의 허락없이 직접 메모리에 접근할 수 있는 권한을 부여한다.
- 메모리 매핑 입출력(Memory Mapped I/O): 직접 메모리 접근을 사용하면 메모리가 복잡해진다. CPU가 사용하는 데이터와 입출력 장치가 사용하는 데이터가 섞여 있다. 이를 위해 CPU가 사용하는 메모리 공간과 직접 메모리 접근을 통해 들어오거나 나가는 데이터를 위한 공간을 분리한다.
- 사이클 훔치기(Cycle stealing): 만약 CPU와 입출력 관리자가 동시에 메모리에 접근하려고 하면 누군가는 양보를 해야한다. 이는 보통 CPU가 메모리 사용 권한을 양보하는데 이는 CPU의 작업 속도보다 입출력장치의 속도가 더 느르기 때문이다. 이러한 상황을 사이클 훔치기라고 한다.
'운영체제 > 기초' 카테고리의 다른 글
9. 프로세스 (0) | 2020.10.16 |
---|---|
8. 병렬처리 (0) | 2020.10.16 |
6. CPU와 메모리(2) (0) | 2020.10.14 |
5. CPU와 메모리(1) (0) | 2020.10.06 |
4. 하드웨어의 기본 구성 (0) | 2020.10.05 |