CPU
중앙처리장치라고도 하며 컴퓨터 시스템에서 가장 핵심적인 역할을 수행하는 부분이다.
레지스터
중앙처리 장치의 속도와 비슷한 고속의 기억장치이며 명령어 주소, 명령어 코드, 연산에 필요한 데이터, 연산 결과등을 임시로 저장한다. 용도에 따라 범용레지스터와 특수목적 레지스터로 구분된다.
중앙처리장치의 종류에 따라 사용할 수 있는 레지스터의 개수와 크기가 다르다.
프로그램을 이루는 데이터와 명령어가 프로그램의 실행 전후로 레지스터에 저장되기 때문에 레지스터에 저장된 값만 잘 관찰해도 비교적 낮은 수준의 프로그램이 어떻게 작동하는지 파악할 수 있다.
특수목적 레지스터
용도 | 명칭 | 기능 |
주소저장 | 메모리 주소 레지스터 (MAR, Memory Address Register) |
읽기와 쓰기 연산을 수행할 주기억장치의 주소를 저장한다 |
프로그램 카운터 (PC, Program Counter) |
다음에 수행할 명령어의 주소를 저장한다 | |
스택포인터 (SP, Stack Pointer) | 스택의 최상위 주소를 저장한다 | |
인덱스 레지스터(IX, IndeX register) | 인덱스 주소 지정 방식에서 인덱스를 저장한다 | |
명령어 저장 | 명령어 레지스터 (IR, Instruction Register) |
현재 실행 중인 명령어를 저장한다 |
데이터 저장 | 메모리 버퍼 레지스터 (MBR, Memory Buffer Register) |
주기억장치에서 읽어온 데이터나 주기억장치에 저장할 데이터를 임시로 저장한다 |
누산기 (AC, ACumulator) | 연산결과를 임시로 저장한다 | |
CPU상태 저장 | 프로그램 상태 레지스터 (PSR, Program Status Register) |
CPU의 현재 상태 정보를 저장한다 |
프로그램 카운터
다른 말로는 명령어 포인터라고도한다. 메모리에서 가져올 명령어의 주소를 저장하고 다음에 실행될 명령어의 위치를 가르킨다.
일반적으로 프로그램 카운터는 명령 실행을 마칠때마다 1씩 증가하게 된다.
명령어 레지스터
현재 실행중인 명령어를 저장하는 레지스터이다. CPU 내의 제어장치는 명령어 레지스터 속 명령어를 해석한 뒤 산술논리연산장치로 하여금 연산하도록 시키거나 다른 부품으로 제어 신호를 보내 해당 부품을 작동시킨다
범용 레지스터
작은 데이터의 임시 저장 공간으로, 연산 처리 및 데이터의 주소를 지정하는 역할을 한다. 일반적으로 CPU 안에는 여러개의 범용 레지스터들이 있다.
플래그 레지스터
플레그 레지스터는 일반적인 레지스터와 달리 여러가지의 상태 값을 저장하는 레지스터이다. 이 레지스터 안에는 하나하나의 비트가 각각 서로 다른 의미를 갖고 있어 독립적으로 사용된다.
종류 | 설명 | 사용예시 |
부호 플래그 | 연산 결과의 부호 | 부호 플래그가 1일경우 연산결과는 음수, 0일경우 연산결과는 양수를 의미한다. |
제로 플래그 | 연산결과가 0일경우 참 | 제로 플래그가 1일 경우의 연산결과는 0, 0일 경우 연산 결과는 0이 아님을 의미 |
캐리플래그 | 연산 결과에 올림수나 빌림수가 발생했는지의 여부 | 캐리 플래그가 1일 경우에는 연산 결과에 올림수나 빌림수가 발생했음을 의미, 0일 경우에는 발생하지 않음을 의미 |
오버플로우 플래그 | 오버플로우가 발생했는지 여부 | 오버플로우 플래그가 1일 경우에는 오버플로우가 발생했음을 의미, 0일 경우에는 발생하지 않음을 의미 |
인터럽트 플래그 | 인터럽트가 가능한지의 여부 | 인터럽트 플래그가 1일경우 인터럽트가 가능함을 의미, 0일 경우 인터럽트가 불가능함을 의미 |
슈퍼바이저 플래그 | 커널 모드로 실행중인지, 사용자 모드로 실행중인지의 여부 | 슈퍼바이저 플래그가 1일경우 커멀모드로 실행중임을 의미, 0일 경우에는 사용자 모드임을 의미 |
스택 포인터
마지막으로 스택에 저장된 데이터의 위치를 가리키는 레지스터이자 스택이 채워진 정도를 나타내는 레지스터이다.
인터럽트
CPU가 프로그램을 실행하고 있을 때 외부 장치의 예외 상황에 의해 일시적으로 프로그램을 중단시키고 특정 작업을 수행하도록 하는 신호이다. 대표적인 예로는 마우스 클릭, 키보드 입력, 프린터 작업등이 있다. 컴퓨터는 현재 진행 중인 작업을 일시 중단하고 인터럽트를 처리한 후, 다시 중단 되었던 작업을 이어간다. 인터럽트는 CPU가 즉시 처리해야 할 작업이 발생했을 때 일어난다.
동기 인터럽트(Synchronous Interrupt)
- 동기 인터럽트는 CPU 내부에서 발생하는 인터럽트이다. CPU가 명령어를 수행하는 도중 예상치 못한 상황에 직면했을 때 발생하며, 이는 보통 프로그램상의 오류나 예외 상황이다.
비동기 인터럽트(Asynchronous Interrupt)
- 비동기 인터럽트는 입출력 장치에 의해 발생한다. 하드웨어 인터럽트라고도 불리며 예외 상황보다는 시스템 상태를 알리는 역할을 한다. 예를 들어 세탁기의 세탁 완료 알림, 전자레인지의 조리 완료 알림같은 역할을 한다.
입출력 장치의 속도가 CPU보다 느리기때문에 CPU는 장치가 작업을 완료할 때까지 대기해야한다. 이를 해결하기 위해 비동기 인터럽트를 사용하여 CPU가 다른 작업을 처리하는 동안 입출력장치가 완료되면 인터럽트를 발생시켜 CPU에 작업완료를 알린다.
비동기 인터럽트 처리순서
- 입출력 장치가 CPU에 인터럽트 요청 신호를 보낸다
- CPU는 실행 사이클이 끝나고 명령어를 인출하기 전에 항상 인터럽트 여부를 확인한다.
- CPU는 인터럽트 요청을 확인하고, 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인한다.
- 인터럽트를 받아들일 수 있다면 CPU는 현재 작업 상태를 스택에 저장한다.
- CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 싱행한다.
- 인터럽트 서비스 루틴이 끝나면, CPU는 스택에 저장된 작업 상태를 복원하여 작업을 재개한다
예외( 동기 인터럽트)
예외의 종류에는 폴트, 트랩, 중단, 소프트웨어 인터럽트 등이 있다.
예외는 프로그램 실행 도중 동기적으로 발생하는 일이다.
폴트는 문제를 일으킨 명령어부터 다시 시작된다. CPU가 명령어를 실행하려고 할 때 명령어 실행을 위해 필요한 데이터가 메모리에 없다면 CPU는 폴트를 발생시키고 보조기억장치로부터 필요한 데이터를 메모리로 가져와 저장한다. CPU는 필요한 메모리를 가지고 왔으므로 다시 실행을 재개한다. 이를 폴트 페이지라 한다.
트랩은 문제를 일으킨 명령어 이후부터 시작한다. 대표적인 사례로는 디버깅의 브레이크 포인트를 꼽을 수 있다. 디버깅을 할 때는 브레크 포인트를 지정하여 특정 코드가 실행되는 순간에 프로그램을 멈추게 할 수 있다. 프로그램을 중단 시키고 디버깅이 끝나면 트랩이 발생한 다음 명령어부터 실행해 나간다.
중단(abort)는 어디서 문제가 발생했는지 알려주지 않고 다시 프로그램을 시작하는 것도 허용하지 않으므로 심각한 하드웨어 문제일 때 발생한다. 반면에 폴트나 트랩은 다시 고쳐질 수 있는 문제이다.
클럭
클럭이란 컴퓨터의 부품을 일사불란하게 움직일 수 있게 하는 시간의 단위이다. 클럭 속도는 헤르츠 단위로 측정된다. 이는 클럭이 1초에 면번 반복되는지 나타낸다. 클럭속도가 높아지면 CPU는 일반적으로 성능이좋아지나 필요 이상으로 높이면 컴퓨터의 발열이 심해지기 때문에 클럭 속도를 높이는것만으로 CPU의 성능을 높이는데는 한계가 있다.
멀티코어와 멀티 스레드
코어란 CPU 내에서 명령어를 읽어 들이고, 해석하고, 실행하는 부품을 의미한다. 여러개의 코어를 포함하고 있는 CPU는 멀티코어 CPU 또는 멀티코어 프로세서라고 부른다. CPU안에 몇개의 코어가 포함되어있는지에 따라 멀티코어 CPU의 명칭이 바뀌게 된다.
스레드
스레드의 사전적의미는 실행 흐름의 단위이다. 하지만 스레드는 프로그래밍 언어와 cpu, 운영체제에도 등장하는 범용성이 높은 용어인탓에 cpu에서 사용하면 하드웨어 스레드 프로그래밍 언어 및 운영체제에서 사용하면 소프트웨어적인 스레드(이하 스레드)로 나누어 기억하면 된다.
하드웨어 스레드란 하나의 코어가 동시에 처리하는 명령어의 단위를 나타낸다. 같은 의미로 멀티스레드 프로세서 혹은 멀티스레드CPU라고 한다. 일반적으로 1코어 1스레드 CPU이다. 명령어를 읽어들이고, 해석하고, 실행하는 부품 2개가 한 번에 4개의 명령어를 처리한다면 2코어 4스레드CPU인것이다.
하드웨어 프로세스는 메모리 속 프로그램의 입장에서 봤을때 한번에 하나의 명령어를 처리하는 1개의 CPU와 다를바 없다. 그래서 하드웨어 스레드를 논리프로세서라고 부르기도 한다.
예) 10개 코어에 20개의 스레드로 구성되어있으면 물리적으론 10개 코어지만 os가 인식할때는 20개의 논리적인 코어로 인식한다.
소프트웨어 스레드란 하나의 프로그램에서 독립적으로 실행되는 단위를 의미한다.
2코어 4스레드 머신이어도 자바프로그램에서는 Exeutors.newFixedThreadPool(100)이라는 식으로 스레드 갯수를 훨씬 많이 설정할 수 있다. 이 스레드는 소프트웨어 상에서 병렬적으로 task를 나누고 일을 할당할 때 쓰인다. 이 스레드가 그대로 하드웨어 스레드에 올라가서 사용된다. 즉 소프트웨어 스레드가 100개가 있다고 하더라도 동시에 실행될 수있는 하드웨어 스레드 갯수와 같다.
예) 4코어 8스레드라는것은 상하권이 나뉜 4세트의 책과 같다. 이 4세트를 가지고 도서관에서 100명의 사람에게 빌려줄 수있다. 비록 한번에 읽을 수 있는 사람은 8명(소프트스레드)밖에 없지만.
나머지 소프트웨어 스레드는 실제로 일할 task가 없어 쉬고있거나 하드웨어 스레드에 올라갈 자신의 차례를 기다린다.
병렬성
작업을 물리적으로 동시에 처리하는 성질이다. 하드웨어 스레드가 4개인 CPU가 4개의 명령어를 동시에 실행하는것처럼 같은 시점에 여러작업을 동시에 처리할 수 있다 이것이 병렬성의 예이다
동시성
동시에 작업하는 것처럼 보이는 성질이다. CPU가 빠르게 작업을 번갈아가며 처리할 경우 사용자의 눈에는 마치 여러 작업이 동시에 처리되고 있는것처럼 보이지만 물리적으로는 같은 시점에 여러 작업이 동시에 처리되고 있는것은 아니다. 이것이 동시성의 예
즉 하드웨어 스레드는 병렬성을 구현하기 위한 물리적인 실행 단위에 가깝고
소프트웨어 스레드는 동시성을 구현하기 위한 논리적인 실행 단위에 가깝다.
파이프라이닝을 통한 명령어 병렬 처리
명령어 병렬처리 기법은 여러 명령어를 동시에 처리하여 CPU를 한시도 쉬지않고 작동시킴으로써 CPU의 성능을 높이는 기법을 말한다.
명령어가 처리되는 과정
- 비슷한 시간 간격으로 나눔
- 명령어 인출
- 명령어 해석
- 명령어 실행
- 결과 저장
같은 단계가 겹치지 않는다면 CPU가 각각의 단계를 동시에 실행할 수 있다는 점이다. CPU는 하나의 명령어가 인출되는 동안 다른 명령어를 실행할 수있고 하나의 명령어가 실행되는동안 연산의 결과를 저장할 수있다.
명령어 파이프라이닝
공장의 생산 라인과 같이 명령어들을 명령어 파이프라인에 넣고 동시에 처리하는 기법이다.
슈퍼스칼라
명령어 파이프라닝에서 조금 더 발전한 슈퍼스칼라라고 하는 명령어 처리기법도 있다. 대부분의 CPU는 여러개의 파이프라인을 이용한다.
CPU 내부에 여러 명령어 파이프라인을 포함하는 구조를 슈퍼스칼라라고한다. 슈퍼스칼라 구조로 명령어 처리가 가능한 CPU는 슈퍼스칼라 프로세서 혹은 슈퍼스칼라 CPU라 한다.
파이프라인 위험
파이프라이닝이 실패하여 성능 향상이 이루어지지 않는 상황을 말한다.
- 데이터위험
- 명령어 간의 데이터 의존성에 발생한다. 모든 명령어들이 전부다 마냥 겹쳐서 실행할 수 있는것은 아님. 이전의 명령어가 끝까지 실행되어야 인출가능한 명령어가 있을 수 있음. 떄론 다른 명령어에 의지하는 명령어가 있을 수도있음
- 제어위험
- 프로그램 카운터의 갑작스러운 변화에 의해 발생한다. 프로그램 카운터 값에 변화가 생겼을때 이로인해 발생하는것을 제어위험이라한다. 오늘 날의 CPU는 이런 제어위험을 방지하기 위해서 분기예측이라고하는 기술을 제공하기도 한다.
- 구조적 위험 또는 자원적 위험
- 명령어들을 겹쳐 실행하는 과정에서 서로 다른 명령어가 동시에 ALU, 레지스터 등 같은 CPU 부품을 사용하려고 할 때 발생한다.
메모리
RAM
RAM - 휘발성 저장장치
- 전원을 끄면 저장하고 있던 데이터와 명령어가 사라짐
- CPU가 실행할 대상을 저장
보조기억장치 - 비휘발성 저장장치
- 전원이 꺼져도 저장된 내용이 유지되며, 보관할 대상을 저장
RAM은 임의 접근 메모리(Random Access Memory)의 약자로 임의 접근이란 저장된 요소에 순차적으로 접근할 필요 없이 임의의 위치에 곧장 접근 가능한 방식을 의미한다. 그래서 직접 접근(direct access)이라고도 부른다.
순차접근은 임의접근과는 다르게 특정 위치에 저장된 요소에 접근하기 위해 처음부터 순차적으로 접근하는 방식이다.
RAM 종류
- DRAM(Dynamic RAM)
- 저장된 데이터가 동적으로 변하는 특성
- 데이터의 소멸을 막기 위해 일정 주기로 데이터를 재활성화(다시저장) - 비교적 DRAM의 소비 전력이 낮고, 저렴하며, 집적도가 높아 대용량 메모리로 쓰기에 적합하여 주기억장치로 사용된다.
- 저장된 데이터가 동적으로 변하는 특성
- SRAM (Static RAM)
- DRAM과 달리 저장된 데이터가 변하지 않는 RAM
- SRAM도 전원이 공급되지 않으면 저장된 내용이 소실된다
- DRAM과 비교해 속도는 빠르지만 소비전력이 크고 비싸고 집적도도 낮음
- 대용량으로 만들필요는 없으나 속도가 빨라야하는 저장장치,캐시 메모리등에서 사용된다
- SDRAM(Synchronous Dynamic RAM)
- 클럭 신호와 동기화된, 보다 발전된 형태의 DRAM
- 클럭 타이밍에 맞춰 CPU와 정보를 주고 받음
- DDR SDRAM(Double Data Rate SDRAM)
- 대역폭을 넓혀 속도를 빠르게 만든 SDRAM
- DDR2 SDRAM은 DDR SDRAM보다 대역폭이 두 배 넓은 SDRAM
- 최근에 흔히 볼 수있는 메모리는 DDR4 SDRAM으로 SDR SDRAM보다 열여섯배 넓은 대역 폭을 가진SDRAM을 말한다
빅 엔디안과 리틀 엔디안
현대의 메모리는 대부분 데이터를 바이트 단위로 저장하고 관리한다. 메모리는 데이터를 CPU로부터 바이트 단위로 받아들이지않고, 일반적으로 4바이트(32비트), 혹은 8바이트(64비트)인 워드 단위로 받아들인다.
여러 바이트로 구성된 데이터를 받아들여 여러 주소에 걸쳐 저장한다.
- 한 주소에 1바이트씩 저장하는 메모리는 4바이트의 데이터를 4개의 주소에 저장하고 8바이트의 데이터를 8개의 주소에 저장한다.
- ex) 16진수인 1A2B3C4D는 1A, 2B, 3C, 4D로 나누어 4개의 주소에 저장되고 16진수 1A2B3C4D5A6B7C8D는 1A,2B,3C,4D,5A,6B,7C,8D로 나누어 9개의 주소에 저장한다.
16진수 하나를 저장하는 데에는 4비트가 필요하다 따라서 16진수 2개를 저장하는 데에는 8비트인 1바이트가 필요하다.
빅 엔디안
낮은 번지의 주소에 상위 바이트부터 저장하는 방식
일상적으로 숫자 체계를 읽고 쓰는 순서와 동일하기 때문에 메모리 값을 직접 읽거나, 특히 디버깅할 때 편리하다. 주소에 1A, 2B, 3C, 4D의 순서대로 저장된 값 그대로 16진수 1A2B3C4D로 읽는다
리틀 엔디안
낮은 번지의 주소에 하위 바이트부터 저장하는 방식
메모리 값을 직접 읽고 쓰기는 불편하지만 수치 계산이 편리하다는 장점이 있다
MSB와 LSB
- MSB(Most Significant Bit) 숫자의 크기에 가장 큰 영향을 미치는 유효 숫자
- 가장 왼쪽에 있는 비트
- LSB(Least Significant Bit) 숫자의 크기에 가장 적은 영향을 미치는 유효 숫자
- 가장 오른쪽에 있는 비트
- ex) 10진수 123에서 MSB 쪽 숫자는 1이고 LSB 쪽 숫자는 3
- 빅 엔디안 - MSB가 있는 바이트, 즉 중요하고 큰 데이터부터 저장해 나가는 방식
- 리틀 엔디안 - LSB가 있는 바이트, 즉 덜 중요하고 작은 데이터부터 저장해 나가는 방식
파이썬 코드로 빅 엔디안 또는 리틀 엔디안 중 어떤 방식을 황용하는 환경인지 확인 할 수있다.
import sys
print(sys.byteorder)
위와 같은 코드를 실행해 big이 출력되면 빅 엔디안 little이 출력되면 리틀 엔디안 환경이다.
빅 엔디안 (>) 방식으로 표기된 107.6640625라는 소수를 16진수로 표현했을때 결과는
42d75400이며
리틀 엔디안(<) 방식으로 표기된 107.6640625라는 소수를 16진수로 표현했을때 결과는
0054d742다
캐시 메모리
CPU의 연산 속도와 메모리 접근 속도의 차이를 줄이기 위해 탄생했다. CPU와 메모리 사이에 위치한 SRAM 기반의 저장장치이다.
코어와 가장 가까운 캐시 메모리는 L1캐시 다음으로 가까운 캐시메모리를 L2 캐시 다음으로 가까운 캐시를 L3캐시라고 한다.
일반적으로 L1캐시와 L2 캐시는 코어 내부에, L3 캐시는 코어 외부에 위치한다.
캐시 메모리의 크기는 L1 < L2 < L3 순으로 크고 속도는 L3 < L2 < L1 순으로 빠르다.
CPU가 메모리 내에 데이터가 필요하다고 판단하면 우선 L1 캐시 메모리에 해당 데이터가 있는지 알아보고 없다면 L2, L3캐시 메모리 순으로 데이터를 검색한다.
멀티 코어 프로세서의 경우 일반적으로 L1 캐시 메모리와 L2 캐시 메모리는 코어마다 고유한 캐시 메모리로 할당한다
L3 캐시는 여러 코어가 공유하는 형태로 구현한다
오늘 날의 캐시는 더 발전해서 L1 캐시의 경우에는 두개를 분리하는 경우가 있는데 이런경우를 분리형 캐시라고한다.
L1I 캐시 - 명령어만을 저장하는 L1 캐시
L1D캐시 - 데이터만을 저장하는 L1캐시
캐시 히트와 캐시 미스
캐시 메모리는 메모리에 있는 내용 전체를 저장할 수 없기 때문에 일부만 저장한다. CPU는 주기억장치로부터 프로그램이나 데이터를 가져올 때 우선적으로 원하는 정보가 캐시 메모리에 존재하는지 검사 후 원하는 정보가 캐시 메모리에 존재하면 바로 읽어오고, 존재하지 않으면 메모리에서 캐시 메모리로 저장한 후 읽어온다.
캐시 적중(cache hit) - 캐시 메모리가 예측하여 저장한 데이터가 CPU에 의해 실제로 사용되는경우
캐시 미스 - 틀린 예측으로 인해 CPU가 메모리로부터 필요한 데이터를 직접 가져와야하는 경우
원하는 정보가 캐시 메모리에 존재할 확률을 나타내는 캐시 적중률은 다음과 같이 정의한다.
캐시 히트 횟수 / (캐시 히트 횟수 + 캐시 미스 횟수)
범용적으로 사용되는 컴퓨터의 캐시 적중률은 대략 85 ~ 95%이상이다
참조 지역성의 원리
캐시메모리는 메모리에 비해서 크기가 작기때문에 메모리에 있는 모든 데이터를 당연히 저장할 수없음 CPU가 사용할 법한 데이터를 예측해서 미리 저장해야한다. 그 과정에서 캐시메모리는 한가지 원칙에 의거해서 CPU가 필요한 데이터를 저장하게 되는데
그 원칙이 바로 참조지역성의 원리이다.
시간지역성 - CPU는 최근에 접근했던 메모리 공간에 다시 접근하려는 경향이 있음 ex) 변수
공간 지역성 - CPU는 접근한 메모리 공간의 근처에 접근하려는 경향이 있음 ex) 배열
메모리 내에 일렬로 저장될 때 2차원 배열은 다음 그림과 같이 행과 열의 순으로 저장된다.
공간 지역성을 고려한 코드, 캐시 친화적인 코드를 작성해야하는것이 아주 중요하다.
캐시 메모리의 쓰기 정책과 일관성
캐시메모리에 데이터를 쓰는경우 CPU가 캐시메모리에 데이터를 쓸 때는 캐시 메모리에 새롭게 쓰여진 데이터와 메모리 상의 데이터가 일관성을 유지해야함
ex) 현재 메모리 1000번지에 200이라는 값이 저장되어 있고, 이 값이 캐시 메모리에도 저장되어 있다고 가정한다. CPU가 이 값에 접근하고자 할 때는 당연히 앞에서 작성한것 처럼 캐시 메모리를 통해 값을 얻어낸다. 이때 만약 CPU가 이 값을 200에서 300으로 바꾸고 싶다면 어떻게 해야할가
메모리 1000번지 값을 무작정 300으로 바꾼다면 다음과 같은 명령어를 수행 할 때 예상치 못한 결과가 발생한다.
캐시 메모리와 메모리 간의 불일치 방지
즉시쓰기 - 캐시 메모리와 메모리에 동시에 쓰는 방법
- 장점 - 메모리를 항상 최신 상태로 유지하여 캐시 메모리와 메모리 간의 일관성이 깨지는 상황을 방지한다
- 단점 - 데이터를 쓸 때마다 메모리를 참조해야 하므로 버스의 사용 시간과 쓰기 시간이 늘어난다.
지연쓰기 - 캐시 메모리에만 값을 써두었다가 추후 수정된 데이터를 한 번에 메모리에 반영한다
- 장점 - 메모리 접근 횟수를 줄일 수 있어 즉시 쓰기 방식에 비해 속도가 더 빠르다
- 단점 - 메모리와 캐시 메모리 간의 일관성이 깨질 수 있다는 위험을 감수해야한다.
캐시 메모리를 사용한다는 것, 나아가 캐싱을 한다는 것은 데이터 접근에 있어 어느정도 빠른 성능은 보장한다. 자주 사용할 법한 대상을 가까이 위치시킴으로써 성능 향상을 꾀한다. 캐싱을 할 때는 언제나 캐시된 데이터와 원본 데이터 간의 불일치와 데이터의 일관성을 고려해야한다.
보조기억장치와 입출력창치
보조기억장치
- 하드 디스크 드라이브(하드디스크, HDD)
- 플래시 메모리 기반 저장장치(SSD)
RAID
데이터의 안전성 혹은 성능을 확보하기 위해 여러 개의 독립적인 보조기억장치를 마치 하나의 보조기억장치처럼 사용하는 기술이다.
RAID를 구성하는 벙법에는 여러가지가 있으며, RAID 레벨이라고 한다.
RAID0,RAID1,RAID2,RAID3,RAID4,RAID5,RAID6이 대표적이며 RAID10,RAID50등이 있다.
RAID0
데이터를 여러 보조기억장치에 단순하게 나누어 저장하는 구성 방식
- 스트라입(stripe) - 마치 줄무늬처럼 분산되어 저장된 데이터
- 스트라이핑(striping) - 분산하여 저장하는 동작
- 장점 - 빠른 입출력 속도
- 4TB인 저장장치 1개보다 RAID0으로 구성된 1TB인 저장장치 4개의 속도가 이론상 4배 가량 빠름
- 단점 - 저장된 정보가 안전하지 않다.
- 만약 하드디스크1에 문제가 생긴다면 하드디스크2,3,4에 저장된 데이터는 불완전한 데이터다
RAID1
완전한 복사본을 만들어 저장하는 구성방식이다. 미러링이라고도 부른다
장점- 복구가 간단하고 안정성이 높다
단점 - 복사본이 저장된 크기만큼 사용 가능한 용량이 적어진다. 원본다 복사본 두 곳에 써야하기 때문에 RAID0보다 쓰기 속도가 느리다
RAID4
패리티 정보를 저장하는 디스크를 따로 두는 구성 방식
패리티란 오류를 검출할 수 있는 정보를 말한다.
장점- RAID1에 비해 적은 하드 디스크로도 안전하게 데이터를 보관한다
단점 - 패리티를 저장하는 장치에 병목 현상이 발생한다
패리티라고 하는 오류검출용 정보는 당연하게도 데이터에 접근할때마다 참조를 해야한다
그렇기 때문에 하드디스크1,2,3에 접근을 하든 읽기를 하든 쓰기를하든 무조건 하드디스크4에 접근해야할 수가 있다 그래서 병목현상이 발생할 수 있음
RAID5
패리티를 분산하여 저장하는 구성방식
RAID4의 단점인 병목 현상을 보완한 방식이다.
RAID6
서로 다른 2개의 패리티를 두는 구성 방식이다. 오류를 검출하고 복구할 수 있는 수단이 2개 - RAID6은 RAID4나, RAID5에 비해 안전성이 높다.
단점은 새로운 정보를 저장할 때마다 함께 저장할 패리티가 2개이므로 RAID5에 비해 쓰기 속도는 느리다.
Nested RAID
여러 RAID 레벨을 혼합한 방식
RAID10 - RIAD0과 RAID1을 혼합
RAID50 - RAID0과 RAID5를 혼합
입출력 기법
장치컨트롤러와 장치 드라이버
장치 컨트롤러
- CPU와 입출력장치 사이의 통신을 중개하는 중개자 역할의 하드웨어
- 모든 입출력장치는 각자의 장치 컨트롤러를 통해 컴퓨터 내부와 연결되어 정보를 교환한다.
장치 드라이버
- 장치 컨트롤러의 동작을 알고, 장치 컨트롤러가 컴퓨터 내부와 정보를 주고받을 수 있도록 하는 프로그램이다
프로그램 입출력
프로그램 속 명령어로 입출력 작업을 수행하는 방법이다
고립형 입출력 - 입출력 장치를 위한 주소공간을 메모리를 위한 주소 공간과 별도로 분리해서 간주하는 방식
메모리 맵 입출력 - 메모리를 위한 주소공관과 입출력장치를 위한 주소공관을 별도로 분리하지 안흔ㄴ 방식
고립형 입출력을 사용할 때는 메모리를 위한 주소공간과 입출력장치를 위한 주소공간이 별도로 분리 되어있기때문에 메모리에 접근하기 위한 명령어와 입출력장치에 접근하기 위한 명령어는 다를 수밖에 없다
메모리 맵은 별로도 분리되어있지 않기 떄문에 메모리에 접근하는 것과 똑같이 입출력장치에 접근할 수 있다.
입출력장치만을 위한 명령어가 필요없음
인터럽트 기반 입출력: 다중 인터럽트
인터럽트가 여러 입출력장치로부터 동시다발적으로 발생하는 경우의 인터럽트 처리이다.
키보드, 마우스, 모니터, 스피커 등의 입출력장치를 동시에 사용하는 상황일 경우 CPU는 동시 다발적으로 발생하는 키보드, 마우스, 모니터, 스피커 인터럽트를 모두 처리해야한다. 이렇게 인터럽트가 여러 입출력장치로부터 동시다발적으로 발생하는경우에는
CPU가 플래그 레지스터 속 인터럽트 비트를 비활성화한 채 인터럽트를 처리할 경우 다른 하드웨어 인터럽트를 받아들이지 않기때문에 CPU는 기본적으로 다음과 같이 인터럽트가 발생한 순서대로 인터럽트 서비스 루틴을 순차적으로 진행한다
일반적으로 인터럽트는 순차적으로만 처리되지 않는다
인터럽트 중에서도 우선순위가 더 높은 인터럽트가 우선적으로 처리되는 경우가 일반적이다.
ex) 현재 CPU가 인터럽트A보다 인터럽트B의 우선순위가 낮다면 CPU는 A를 모두 처리한 뒤에 B를 처리한다. 인터럽트의 A보다 B의 우선순위가 높다면 CPU는 인터럽트A의 실행을 잠시 멈추고 B를 처리한 뒤에 다시 A를 처리한다.
CPU는 플래그 레지스터 속 인터럽트 비트가 활성화되어 있는 경우, 혹은 인터럽트 비트를 비활성화해도 무시할 수 없는 인터럽트인 NMI(Non-Maskable Interrupt)가 발생한 경우, 우선순위가 높은 인터럽트부터 처리한다
프로그래머블 인터럽트 컨트롤러 (PIC, Programmable Interrupt Controller)
다중 인터럽트를 처리하기 위해 사용되는 하드웨어이다. PIC는 여러 장치 컨트롤러에 연결되어 있어 장치 컨트롤러에서 보낸 하드웨어 인터럽트 요청들의 우선순위를 판별한 뒤, CPU에게 지금 처리해야 할 하드웨어 인터럽트가 무엇인지를 알려주는 장치이다.
PIC 각각의 핀에는 CPU에게 하드웨어 인터럽트 요청을 보낼 수 있도록 약속된 하드웨어가 연결되어 있다.
오늘날의 컴퓨터의 경우에는 다른 PIC가 계층적으로 연결되어있는 경우가 많음
이렇게 2개 이상의 계층으로 구성되어있는경우 훨씬 더 많은 인터럽트의 요청신호들을 받아들여서 우선순위를 판단한다
DMA 입출력
프로그램 기반의 입출력과 인터럽트 기반의 입출력에 공통점이있다.
CPU가 입출력장치와 메모리 간의 데이터 이동을 주도해야하며, 이동하는 데이터들도 반드시 CPU를 거친다
ex1) 입출력 장치의 데이터를 메모리에 저장하는 경우
- CPU는 장치컨트롤러로부터 데이터를 하나씩 읽어 레지스터에 적재, 적재한 데이터를 하나씩 메모리에 저장한다
ex2) 메모리 속 데이터를 입출력장치에 내보내는 경우
CPU는 메모리로부터 데이터를 하나씩 읽어 레지스터에 적재, 적재한 데이터를 하나씩 입출력 장치에 내보낸다.
만약 입출력력작업이 많아질 경우에는 이렇게 데이터 이동이 반드시 CPU를 거쳐야 할 경우에는 CPU에 과부화가 생길 수 있다.
그래서 입출력장치와 메모리간에 데이터 이동이 있을경우에 CPu를 거치치 않고 직접 메모리에 접근할 수있게끔 하는 입출력 기법이 DMA이다.
DMA (Direct Memory Access)
CPU를 거치치 않고도 입출력장치와 메모리가 상호작용할수 있는 입출력방식이다. DMA 입출력을 위해서는 시스템 버스에 연결된 DMA z컨트롤러라는 하드웨어가 필수적이다.
DMA컨트롤러는 입출력장치들이 연결되어 있는 입출력버스에 연결이 된다. 입출력버스에는 여러 장치컨트롤러와 그와 연관된 입출력 장치들이 연결되어있다.
DMA 입출력 과정
- CPU가 DMA 컨트롤러에게 입출력장치의 주소, 수행할 연산, 연산할 메모리 주소 등의 정보와 함께 입출력 작업을 명령한다
- DMA컨트롤러가 CPU 저장 장치 컨트롤러와 상호작용하며 입출력 작업을 수행한다. 이때 DMA 컨트롤러는 필요한 경우에 메모리에 직접 접근하여 정보를 읽거나 쓴다.
- DMA 컨트롤러는 입출력 작업이 끝나면 CPU에게 인터럽트를 통해 작업이 끝났음을 알린다.
CPU 입장에서는 DMA 컨트롤러에게 입출력 작업 명령을 내리고 인터럽트만 받으면 되기때문에 입출력 부담을 크게 줄일 수 있다.
DMA와 관련한 사이클 스틸링이라는 개념도 같이 알아둘것.
사이클 스틸링
DMA컨트롤러가 시스템 버스를 사용하는 양상을 나타내는 단어이다.
버스는 공용자원이다. 두 장치가 동시에 하나의 버스를 이용할 수없다. CPU가 이용할땐 DMA 컨트롤러가 이용할수없고 반대로도 똑같음
따라서 DMA 컨트롤러는 CPU가 시스템 버스를 사용하지 않을때 조금씩 사용하거나 CPU가 시스템 버스 사용을 양보한다
이런 의미로 DMA 시스템 버스 사용을 사이클 스틸링이라고한다
PCIe(Peripheral Component Interconnect express)
PCIe 버스는 PCI라는 입출력 버스의 발전된 형태이다. 오늘날의 메인보드에서 가장 대중적으로 볼 수 있는 입출력 버스중 하나이다. SSD,GPU등 오늘날에 사용되는 입출력장치들이 PCIe 버스에 연결될수있다.
PCIe와 연결된 장치의 성능
PCIe 버전에 따라 최대 속도가 달라질 수 있다.
PCIe 버스는 지속적으로 발전하며 PCIe 버스의 버전은 PCIe 3.0, PCIe 4.0, PCIe 5.0와 같이 PCIe 뒤에 버전을 나타내는 숫자를 덧붙이며 버전에 따라 지원되는 최대 속도가 다르다.
PCIe 버스는 여러 레인을 이용해 정보를 주고받는다.
레인(lane) - PCIe 버스를 통해 정보를 송수신하는 단위
'x 레인 수' 와 같이 표기한다. -PCIe4.0 x4는 4개의 레인을 활용하는 PCIe 4.0을 의미한다.
'cs' 카테고리의 다른 글
02. 컴퓨터 구조 (1,2) (0) | 2025.01.22 |
---|