캐시란?

CPU의 처리속도와 메모리의 속도 차이로 인한 병목현상을 완화하기 위해 사용하는 고속 버퍼 메모리이다.
메인 메모리에 있는 데이터를 액세스하려면 오랜 시간이 걸린다. 이런 시간을 줄이기 위해 중간에 캐시 메모리를 두었다.
주기억장치 내 자주 읽고 쓰는 데이터의 일부를 캐시 메모리에 불러와 속도 차이를 줄이고, 주기억장치와 CPU간 신호 교환에 이용되는 Memory Bandwidth를 I/O사용에 집중할 수 있어 성능 향상의 결과를 불러온다.

캐시의 종류

  • L1 Cache :프로세서와 가장 가까운 캐시, 속도를 위해 아래 두가지로 나눈다.
    • IC(Instruction Cache) : 메모리에서 text영역의 데이터를 다루는 캐시
    • DB(Data Cache) : 메모리에서 text영역을 제외한 모든 데이터를 다루는 캐시
  • L2 Cache : 용량이 큰 캐시, 크기를 위해 L1과 같이 나누지 않는다.
  • L3 Cache : 멀티 코어 시스템에서 여러 코어가 공유하는 캐시

캐시의 지역성

자주 사용하는 데이터에 관한 판단은 지역성의 원리를 따르며, 지역성의 전제조건으로 프로그램은 모든 코드나 데이터를 균등하게 access하지 않는다라는 특성을 기본으로 한다. 즉, 지역성이란 기억장치 내의 정보를 균등하게 access하는 것이 아니라 어느 한 순간에 특정 부분을 집중적으로 참조하는 특성이다.
지역성 원리는 시간지역성(Temporal Locality)공간지역성(Spatial locality)로 구분하여 볼 수 있다.



시간적 지역성

최근 액세스된 기억 장소가 가까운 미래에 다시 반복될 가능성이 높다.

  • 사례 : for-loop에서의 i와 같은 공통변수, LRU(가장 오랫동안 참조되지 않는 페이지가 교체되는 알고리즘)

공간적 지역성

액세스된 기억장소와 인접한 기억장소가 액세스 될 가능성이 높다.

  • 사례 : array의 순차적 접근

캐시의 성능측정지표

CPU가 메인 메모리에 접근하기 전 캐시 메모리에서 원하는 데이터의 존재 여부를 확인하는데, 이 때 필요한 데이터가 있을 경우 Hit(적중), 없는 경우 Miss(실패)라고 한다. 요청한 데이터를 캐시 메모리에서 찾을 확률은 Hit Ratio(적중률)이라고 하며, 아래와 같은 식으로 계산한다.

적중률을 극대화 하기 위해 캐시는 위 지역성(Locality의 원리를 사용한다. 캐시의 성능을 측정할 때에는, 히트 레이턴시(Hit latency)와 미스 레이턴시(Miss latency)가 중요한 요인으로 꼽힌다.

캐시 적중률 = 캐시 적중 회수 / 전체 메모리 접근 회수

보통 CPU는 데이터를 가져오기 위해 캐시 메모리 > 메모리 > 보조기억장치 순으로 접근한다.

  • 캐시 적중 : 캐시 메모리의 데이터를 CPU 레지스터에 복사한다.
  • 캐시 실패/ 메모리 적중 : 메모리의 데이터를 캐시 메모리에 복사하고, 캐시 메모리의 복제된 내용을 CPU 레지스터에 복사
  • 캐시, 메모리 실패 : 보조기억장치의 데이터를 메모리에 복사한다. 메모리에 복제된 내용을 캐시메모리에 복제하고, 마지막으로 캐시 메모리의 복제된 데이터를 CPU 레지스터에 복제한다.

###캐시 메모리의 기본 구성 및 동작 CPU는 데이터를 요청할 때마다 캐시 메모리에서 해당 데이터의 존재여부를 확인한다.
따라서 캐시 메모리는 요청받은 데이터를 탐색하는 기능이 필요하다. 캐시 메모리는 데이터를 관리하기 위해 데이터 메모리태그 메모리를 사용한다.

  • 블록 : 캐시의 기본 단위 구성, 각각의 블록은 데이터를 담고 있으며, 주소값을 키로써 접근할 수 있다. 블록의 개수와 크기가 캐시의 크기를 결정한다.
  • 데이터 메모리 : 메모리의 데이터들이 저장된 블록
  • 태그 메모리 : 데이터 메모리의 블록을 탐색할 정보를 포함한다.
    • 태그 메모리의 엔트리는 데이터 메모리 블록과 쌍을 이루며 태그, 유효 비트, 갱신 비트를 포함한다. 또한 CPU주소와 태그를 비교하는 비교기를 가지고 있다.
    • 태그 : CPU가 요청한 데이터를 탐색하는데 사용할 주소의 일부. 캐시 블록 주소에서 인덱스로 사용되지 않는 부분이다.
    • 유효 비트 : 캐시 블록이 유효한 데이터인지 나타낸다.
    • 갱신 비트 : 캐시로 블록을 가져온 후 CPU가 블록을 수정했는지 나타낸다.

기본 동작 흐름

  • CPU가 캐시에 주소 전송 > 태그 메모리 탐색 > 일치하는 태그 발견 (hit) > 블록 상태 갱신(필요시) > 데이터 메모리에서 블록 추출 > 요청받은 데이터 선택 > 캐시가 CPU에 데이터 전송
  • CPU가 캐시에 주소 전송 > 태그 메모리 탐색 > 일치하는 태그 없음(miss) > 주소를 메모리로 전송해 대응하는 블록을 캐시에 저장 > 요청받은 데이터 선택 > 캐시가 CPU에 데이터 전송

Caching Line

캐시는 프로세스 가까이에 위치하며 빈번하게 데이터를 놔두는 장소이다. 그러나 캐시가 아무리 가까이 있더라도, 정리가 안 된 가방처럼 필요한 것이 어디에 있는지 모르고 내용물을 뒤엎어 데이터를 찾는다면 결국 시간이 오래 걸리게 된다. 즉, 캐시에 찾고자 하는 데이터가 있을 경우, 이를 빠르게 꺼낼 수 있어야만 의미가 있다는 것이다.
그렇기 때문에 캐시를 저장할 때 특정 자료구조를 사용해 묶음으로 저장하게 되는데 이를 캐싱 라인이라고 한다. 다양한 주소에 있는 데이터를 사용하므로 빈번하게 사용되는 주소는 흩어져 있다. 따라소 캐시에 저장하는 데이터에 데이터의 메모리 주소를 기록해둔 태그를 달아놓을 필요가 있다. 이런 태그의 묶음을 캐싱 라인이라고 하고, 메모리로부터 가져올 때도 캐싱라인을 기준으로 가져온다. 대표적인 종류는 아래 세가지 방식이 있다.

  1. Full Associative
  2. Set Associative
  3. Direct Map

참고 자료 :

  1. 💵 캐시가 동작하는 아주 구체적인 원리
  2. 캐시 메모리(cache memory)의 개요 정리

oksusutea's blog

꾸준히 기록하려고 만든 블로그