
현대 컴퓨터 구조의 가장 큰 문제는 CPU와 메모리, 주변장치의 작업 속도가 다르다는 것입니다. 이 절에서는 이러한 장치 간 속도 차이를 개선하고 시스템의 작업 속도를 올리기 위해 개발된 기술 중 운영체제와 관련된 것을 살펴볼 것입니다.
버퍼 (buffer) : 두 장치 사이의 속도 차이를 완화하는 역할
입출력장치에서 데이터를 읽을 때마다 하나씩 전송하면 작업량에 비해 실제 전송되는 양은 매우 작습니다. 하지만, 일정량의 데이터를 모아 한꺼번에 전송하면 적은 작업량으로도 많은 양의 데이터를 옮길 수 있습니다. 이렇게 일정량의 데이터를 모아서 옮겨 속도 차이를 완화하는 장치가 버퍼입니다.
하드디스크 사양은 1TB, 7200rpm, 256MB 이라면, 이는 하드디스크 용량이 1TB, 디스크 회전 속도가 7200rpm, 버퍼 용량이 256MB라는 의미입니다. 같은 사양의 하드디스크라면 버퍼 용량이 큰 것이 더 빠릅니다.
버퍼는 하드웨어에서만 사용되는 개념이 아닙니다. 버퍼가 소프트웨어에서 사용되는 대표적인 예는 동영상 스트리밍입니다. 플레이어가 재생되는 도중에 데이터가 도착하지 않으면 동영상이 끊기는데, 이러한 현상을 방지하기 위해 동영상 데이터의 일정 부분을 버퍼에 넣은 후 실행합니다.
스풀 (SPOOL; Simultaneous Peripheral Operation On-Line)
: CPU와 입출력장치가 독립적으로 동작하도록 고안된 소프트웨어적인 버퍼
대표적인 예는 프린터에 사용되는 스풀러(spooler)입니다. 스풀러는 버퍼의 일종이지만 다른 점이 있습니다. 프로그램이 버퍼를 공유하기 때문에 어떤 프로그램의 데이터이든 버퍼가 다 차면 이동이 시작됩니다. 반면에 스풀러는 한 인쇄물이 완료될 때까지 다른 인쇄물이 끼어들 수 없으므로 프로그램 간에 배타적입니다.
캐시 (cache) : 메모리와 CPU 간의 속도 차이를 완화하기 위해 메모리의 데이터를 미리 가져와 저장해 두는 임시 장소
캐시는 필요한 데이터를 모아 한꺼번에 전달하는 버퍼의 일종입니다. 다시말해 필요하다고 생각되는 일정량의 데이터를 미리 가져와 저장해 두는 곳이 캐시입니다.
캐시는 빠른 속도로 작동하는 CPU와 느린 속도로 작동하는 메모리 사이에서 두 장치의 속도 차이를 완화해 줍니다.
캐시는 메모리의 내용 중 일부를 미리 가져오고 CPU는 메모리에 접근할 때 먼저 캐시를 방문하여 원하는 데이터가 있는지 찾아봅니다. 캐시에서 원하는 데이터를 찾았을 때 캐시 히트(cache hit)라고 하며 그 데이터를 바로 사용합니다. 그러나 원하는 데이터가 캐시에 없으면 메모리로 가서 데이터를 찾는데 이를 캐시 미스(cache miss)라고 합니다.
캐시 히트가 되는 비율을 캐시 적중률(cache hit ratio)이라고 하며 일반적인 컴퓨터의 캐시 적중률은 90% 입니다.
컴퓨터의 성능을 향상하려면 캐시 적중률을 높여햐 하는데, 이를 높이는 방법 중 하나는 캐시의 크기를 늘리는 것입니다.
캐시 적중률을 높이는 또 다른 방법은 데이터를 가져오는 것인데, 이와 관련된 이론으로는 현재 위치에 가까운 데이터가 멀리 있는 데이터보다 사용될 확률이 더 높다는 지역성(locality) 이론이 있습니다.
캐시는 메모리에 있는 데이터를 임시로 가져온 것이기 때문에 캐시에 있는 데이터가 변경되면 메모리에 있는 원래 데이터를 변경해야 합니다. 캐시의 변경된 데이터를 메모리에 반영하는 데에는 즉시 쓰기 방식과 지연 쓰기 방식이 있습니다.
프로그램의 명령어는 크게 어떤 작업을 할지 나타내는 명령어 부분과 작업 대상인 데이터 부분으로 나눌 수 있습니다.
레벨별 캐시의 구조에서 명령어 캐시는 명령어 레지스터와 연결되어 있고, 데이터 캐시는 데이터 레지스터와 연결되어 있습니다. 명령어 캐시나 데이터 캐시는 CPU 레지스터에 직접 연결되기 때문에 L1(Level 1) 캐시라 부르고, 일반 캐시는 메모리와 연결되기 때문에 L2(Level 2) 캐시라 부릅니다.
저장장치의 계층 구조는 속도가 빠르고 값이 비싼 저장장치를 CPU 가까운 쪽에 두고, 값이 싸고 용량이 큰 저장장치를 반대쪽에 배치하여 적당한 가격으로 빠른 속도의 큰 용량을 동시에 얻는 방법입니다.
컴퓨터는 CPU와 메모리의 협업으로 작업하지만 메모리 속도가 CPU보다 느립니다. 저장장치의 계층 구조에서는 CPU와 가까운 쪽에 레지스터나 캐시를 배치하여 CPU가 작업을 빨리 진행할 수 있게 합니다. 또한 메모리에서 작업한 내용을 하드디스크와 같이 저렴하고 용량이 큰 저장장치에 저장할 수 있게 합니다. 저장장치의 계층 구조는 사용자가 저렴한 가격으로 용량은 하드디스크처럼 사용하고 작업 속도는 레지스터처럼 빠르게 만들어 줍니다.
초기의 컴퓨터 시스템에는 주변장치가 많지 않았고, 당시에는 CPU가 직접 입출력장치에서 데이터를 가져오거나 내보냈는데, 이를 폴링(polling) 방식이라고 합니다.
폴링 방식에서는 CPU가 입출력장치의 상태를 주기적으로 검사하여 일정한 조건을 만족할 때 데이터를 저리합니다. 따라서 CPU가 명령어 해석과 실행이라는 본래 역할 외에 모든 입출력까지 관여해야 하므로 작업 효율이 떨어집니다.
오늘날의 컴퓨터에는 주변장치가 많기 때문에 CPU가 모든 입출력에 관여하면 작업 효율이 현저하게 떨어집니다. 이러한 문제를 해결하기 위해 등장한 것이 인터럽트(interrupt) 방식입니다.
인터럽트 방식
: CPU의 작업과 저장장치의 데이터 이동을 독립적으로 운영함으로써 시스템의 효율을 높임
즉, 데이터의 입출력이 이루어지는 동안 CPU가 다른 작업을 할 수 있습니다.
[ 인터럽트의 동작과정 ]
인터럽트 : 입출력 관리자가 CPU에 보내는 완료 신호
CPU는 입출력 관리자에게 작업 지시를 내리고 다른 일을 하다가 완료 신호를 받으면 하던 일을 중단하고 옮겨진 데이터를 처리합니다. 이처럼 하던 작업을 중단하고 처리해야 하는 신호라는 의미에서 인터럽트라는 이름이 붙었습니다.
인터럽트 방식에서는 많은 주변장치 중 어떤 장치의 작업이 끝났는지를 CPU에 알려주기 위해 인터럽트 번호(interrupt number)를 사용합니다. 인터럽트 번호는 완료 신호를 보낼 때 장치의 이름 대신 사용하는 고유 번호로서 운영체제마다 다릅니다. 윈도우 운영체제의 경우 인터럽트 번호를 IRQ(Interrupt ReQuest)라고 부르며 키보드의 IRQ는 1번, 마우스의 IRQ는 12번, 첫번째 하드디스크의 IRQ는 14번과 같이 구분해서 사용합니다.
CPU는 입출력 관리자에게 여러 개의 입출력 작업을 동시에 시킬 수 있습니다. 이 경우 여러 작업이 동시에 완료되고 그때마다 인터럽트를 여러 번 사용해야 하는데 이는 매우 비효율적입니다. 그래서 여러 개의 인터럽트를 하나의 배열로 만든 인터럽트 벡터(interrupt vector)를 사용합니다.
메모리에서 실행 중인 어떤 작업이 자신에게 주어진 메모리 영역을 넘어서 작업하거나 0으로 숫자를 나눌 때도 인터럽트가 발생합니다.
메모리는 CPU만 접근 권한을 가진 작업 공간이라 입출력 관리자는 접근이 불가능합니다. 따라서 입출력 관리자에게는 CPU의 허락 없이 메모리에 접근할 수 있는 권한이 필요한데, 이것을 직접 메모리 접근(DMA)이라고 합니다.
직접 메모리 접근은 인터럽트 방식의 시스템을 구성하는 필수 요소입니다. 그러나 직접 메모리 접근을 사용하면 메모리가 복잡해집니다.
CPU가 사용하는 메모리 공간과 직접 메모리 접근을 통해 들어오고 나가는 데이터를 위한 공간을 분리하는 것입니다. 이렇게 메모리의 일정 공간을 입출력에 할당하는 기법을 메모리 맵 입출력(MMIO; Memory Mapped I/O)이라고 합니다.
보통은 CPU가 메모리 사용 권한을 양보합니다. CPU 입장에서는 직접 메모리 접근이 사이클(순서)을 훔쳐 간 것이 되기 때문에 이러한 상황을 사이클 훔치기(cycle stealing)라고 부른다.
과거에는 컴퓨터 한 대에 프로세서(CPU)가 하나 달린 시스템이었습니다. 이를 단일 프로세서 시스템(single processor system)이라 부릅니다.
컴퓨터의 성능을 높이기 위해 프로세서를 여러 개 설치하여 사용하는 시스템을 멀티 프로세스 시스템(multi processor system)이라 부릅니다. 멀티 프로세서 시스템에서는 프로세서마다 레지스터와 캐시를 가지며, 모든 프로세서가 시스템 버스를 통하여 메인메모리를 공유합니다.
프로세서가 하나만 있는 단일 프로세서 시스템을 멀티 프로세서 시스템으로 바꾸기 위해서는 보드의 설계 변경을 비롯해 많은 변화가 필요합니다. 그런데 기존 시스템을 유지한 채 멀티 프로세싱을 할 수 있게 하는 시스템이 바로 멀티코어(multi-core) 시스템입니다.
병렬 처리 (instruction processing)
: 하나의 코어에서 여러 개의 명령어를 동시에 처리하는 것
스레드란 CPU가 처리할 수 있는 작업의 단위를 나타냅니다. 여러 개의 스레드를 동시에 처리하는 방법을 CPU 멀티스레드(multi-thread)라고 합니다.
명령어 병렬 처리를 사용하면 코어는 하나이지만 2개의 명령어가 거의 동시에 처리되기 때문에 마치 코어가 2개 있는 것처럼 보입니다. 이러한 병렬 처리 방식을 인텔 CPU에서는 하이퍼스레드(hyper thread)라 부릅니다.
[ CPU 관련 통용 법칙 ]
무어의 법칙 : 인텔의 공동 창업자인 고든 무어는 CPU 속도가 24개월마다 2배 빨라진다고 주장
암달의 법칙 : 주변장치의 향상 없이 CPU 속도를 2GHz에서 4GHz로 늘리더라도 컴퓨터 성능이 2배 빨라지지는 않음
[메모용]
Kay님 피드백
저장장치의 계층 구조는 간단한 삽도를 추가하는 것이 이해에 더 도움이 될 듯