메모리 장치의 계층 구조
[레지스터] - [캐시 메모리] - [메모리] - [저장장치]
크기 작음 <----------------------> 크기 크다
가격 비쌈 <----------------------> 가격 저렴
속도 빠름 <----------------------> 속도 느림
컴퓨터의 동작 흐름
- 명령어를 바탕으로 메모리에서 레지스터로 데이터를 읽는다.
- 레지스터에 있는 데이터를 바탕으로 계산을 수행한다.
- 계산 결과를 메모리에 쓴다.
컴퓨터는 레지스터에서 계산하는 시간보다 메모리에 접근하는 데 걸리는 시간, 레이턴시가 극도로 느리다. (2)단계가 아무리 빨라도 (1)과 (3)단계에서 병목이 발생하여 전체 처리속도는 메모리에 읽고 쓰는 레이턴시와 별 차이가 없게 되버린다.
캐시 메모리
캐시 메모리를 통해 레지스터 안에서 계산하는 것과 메모리에 접근하는 것 양 쪽 처리 시간의 차이를 메운다. [레지스터] - [캐시 메모리]의 레이턴시가 [레지스터] - [메모리]의 레이턴시보다 훨씬 빠른 것을 이용하여 (1), (3) 단계의 속도를 고속화한다. 메모리에서 레지스터에 읽어올 때는 우선 캐시 메모리에 읽어온 뒤 같은 내용을 다시 레지스터에서 읽어 들인다. 읽어오는 크기는 CPU에서 정한 캐시 라인 사이즈(Cache line size)만큼이다.
캐시 메모리에서 읽기
CPU가 물리 메모리에서 데이터를 한 번 읽고, 같은 데이터를 다시 읽으려고 하면 물리 메모리에 접근할 필요 없이 캐시 메모리에 있는 데이터를 읽으면 된다. 물리 메모리에 접근할 필요가 없기 때문에 속도를 빠르게 할 수 있다. (데이터를 읽기 위해 레지스터가 기다리는 시간을 줄인다.)
CPU가 캐시 메모리에 있는 데이터에만 접근할 때 모든 접근이 캐시 메모리의 속도로 처리되므로 캐시 메모리가 없는 경우보다 훨씬 빠르게 처리된다.
캐시 메모리에 쓰기
레지스터로부터 물리 메모리에 데이터를 써넣는 경우에는 일단 변경된 데이터를 캐시 메모리에 적어둔다. 이때 캐시 라인은 데이터가 변경되었음을 나타내는 플래그를 표시하며 이런 플래그가 표시된 캐시 라인을 더티라고 부른다. 더티 플래그가 붙어있는 캐시라인은 써넣은 시점보다 나중에 백그라운드처리로 메모리에 기록되며 캐시 라인은 더티가 아니게 된다.
캐시 메모리가 가득 찬 경우
캐시 메모리가 가득 찬 경우 캐시 메모리에 존재하지 않는 데이터를 추가로 읽으면 기존 캐시 메모리 중 1개를 파기한다. 파기하는 캐시가 더티라면 대응되는 메모리에 덮어쓴 다음 버리는 동기화 작업이 일어난다. (1)캐시 메모리가 가득차고, (2)모든 캐시 라인이 더티라면 메모리에 접근할 때마다 캐시 라인 안의 데이터가 자주 바뀌는 스래싱(thrashing)이 발생하여 성능이 감소할 수 있다.
계층형 캐시 메모리
x86_64 아키텍처의 CPU는 캐시 메모리가 계층형 구조로 되어있다. 각 계층은 사이즈, 레이턴시 등의 차이가 있다. 각 캐시 메모리는 'L1', 'L2', 등의 이름이 붙어있으며 숫자가 작은 캐시가 가장 용량이 적으며 레지스터에 가깝고 빠르다.
메모리 참조의 국소성
프로세스의 데이터가 전부 캐시에 있는 동안에는 데이터에 접근하는 속도는 메모리에 접근하는 속도가 아니라 캐시 메모리에 접근하는 속도가 되며 이러한 상황이 가장 이상적이다. 대부분은 그렇게 작동하며 이를 메모리 참조의 국소성(locality of reference)이라는 특성이라고 한다.
- 시간 국소성: 특정 시점에 접근하는 데이터는 가까운 미래에 다시 접근할 가능성이 크다. (루프 처리 중인 코드 영역)
- 공간 국소성: 특정 시점에 어떤 데이터에 접근한다면, 그 데이터와 가까운 주소에 있는 데이터에 접근할 가능성이 크다. (배열의 전체 검색)
이러한 이유로 프로세스는 자신이 획득한 메모리의 총량보다 훨씬 좁은 범위의 메모리에 접근하는 성향이 있다. 이 좁은 범위를 캐시 메모리가 모두 커버할 수 있다면 성능이 좋은 것이라 할 수 있다. 다른 말로, 프로그램의 워크로드를 캐시 메모리 사이즈에 들어가게 하는 것으로 성능을 크게 향상시킬 수 있다.
Translation Lookaside Buffer
프로세스는 다음과 같은 순서로 가상 주소의 데이터에 접근한다.
- 물리 메모리상에 존재하는 페이지 테이블을 참고하여 가상 주소를 물리 주소로 변환한다.
- (1)에서 구한 물리 메모리에 접근한다.
캐시 메모리를 사용하여 고속화하는 것은 (2)뿐이다. (1)은 물리 메모리에 있는 페이지 테이블에 접근해야 하므로 캐시가 작동할 수 없다. 이 문제를 해결하기 위해 CPU에는 가상 주소에서 물리 주소로의 변환표를 보관하고, 캐시 메모리와 똑같이 고속으로 접근 가능한 Translation Lookaside Buffer(TLB)라는 영역이 있다. 이를 이용해 (1)을 고속화한다.
페이지 캐시
CPU로부터 메모리에 접근하는 비해 저장 장치에 접근하는 속도가 느린 것을 극복하기 위해 페이지 캐시 기능이 있다. 페이지 캐시가 메모리의 데이터를 캐싱하는 것과 비슷하게 페이지 캐시는 저장 장치 내의 파일 데이터를 메모리에 캐싱한다. 캐시 메모리는 캐시 라인의 사이즈 단위로 데이터를 다루고 페이지 캐시는 페이지 단위로 데이터를 다룬다.
읽기
프로세스가 파일의 데이터를 읽어들이면 일단 커널의 메모리 내에 있는 페이지 캐시라는 영역에 복사한 뒤, 이 데이터를 프로세스 메모리에 복사한다. 커널에는 자신의 메모리 안에 페이지 캐셍 캐싱한 파일에 대한 정보를 보관하는 관리 영역을 가지고 있다. 페이지 캐시에 존재하는 데이터를 다시 읽으면 커널은 파일에서 데이터를 읽지 않고 페이지 캐시의 데이터를 되돌려준다. 페이지 캐시는 전체 프로세스의 공유 자원이므로 읽어 들이는 프로세스가 파일 데이터에 접근한 최초 프로세스와 달라도 문제가 없다.
쓰기
프로세스가 데이터를 파일에 쓰면 커널은 우선 페이지 캐시에 데이터를 쓴다.(이 단계에서 물리 메모리의 데이터와 페이지 캐시의 데이터는 같고, 페이지 캐시의 데이터와 파일 데이터는 서로 다르다.) 캐시 메모리와 마찬가지로 저장 장치의 내용보다 새로운 것이라는 플래그를 붙이며 이 플래그가 붙은 페이지를 더티 페이지라고 부른다. 이는 나중에 커널의 백그라운드로 처리한다.
각 프로세스가 접근하는 파일 데이터가 전부 페이지 캐시에 있으면 시스템 파일의 접근 속도는 저장 장치의 접근 속도가 아니라 메모리 접근 속도에 근접하며 시스템 전체의 속도가 빨라진다.
쓰기 전체
시스템 메모리에서의 페이지 캐시
페이지 캐시 사이즈는 시스템의 메모리가 비어 있는 한 시스템 내의 프로세스가 페이지 캐시에 없는 파일을 읽을 때마다 점점 증가한다. 시스템 메모리가 부족해지면 커널은 페이지 캐시를 해제하여 빈 영역을 만든다. 이 경우 더티가 아닌 페이지를 파기하며, 그래도 시스템 메모리가 부족하면 더티 페이지를 쓰기 처리한 후 파기한다. 더티 페이지는 저장 장치에 접근하는 단계가 필요하므로 시스템 성능이 저하되는 현상이 있다.
버퍼 캐시
페이지 캐시와 비슷한 구조로 버퍼 캐시라는 것이 있는데 이는페이지 캐시와 버퍼 캐시를 합쳐서 저장장치 안의 데이터를 메모리에 넣어두는 방식이다. 파일시스템을 사용하지 않고 디바이스 파일을 이용하여 저장 장치에 직접 접근하는 등의 목적으로 사용한다. (파일시스템 챕터에서 자세히 알아봄)
'Computer Science > Computer Architecture' 카테고리의 다른 글
System Bus (0) | 2022.02.13 |
---|---|
PIO(Programmed I/O)와 DMA(Direct Memory Access) (0) | 2022.02.13 |
컴퓨터 시스템의 기본 (0) | 2022.02.08 |
메모리관리 (0) | 2022.02.05 |