CSAPP: 6장 메모리 계층구조 1~4장 [ 크래프톤 정글 31일 차 ]

jinsung·2025년 6월 12일

크래프톤 정글 9기

목록 보기
29/59

저번에 포스팅한 기본 컴퓨터 시스템구조를 통해서 메모리는 용량이 클수록 느리고, 작을수록 빠르다는 물리적 한계가 있다는 사실을 알고 있었어요.

그래서 캐시메모리가 중요하다는 사실을 인지하고 있었는데

이번 6장 "메모리 계층구조"를 통해서 메모리를 어떻게 관리하고 다루는지 공부해 보자구요.

6장. 메모리 계층구조

지금까지 우리가 CSAPP 1~5장의 내용들에 대해서는

전통적인 모델로 CPU와 메모리만을 고려해서 작성되었어요. 메모리를 선형적인 배열로 보고 일정 시간 내에 접근 가능한것으로 가정해서 진행했는데

실제로 우리는 메모리 시스템이 계층구조의 다양한 캐시메모리를 사용하고 있다는 것을 알고 있죠?

만약 우리가 시스템이 어떻게 데이터를 메모리 계층구조에서 위아래로 이동시키는지 이해한다면

데이터를 계층 상위에 저장시켜서 CPU가 보다 빨리 접근할 수 있도록 코드를 작성할 수 있지 않을까요?

사실 이건 "지역성"이라고 부르는 개념이예요.

지역성이 뭔지는 이후 장에서도 살펴볼게요.

그래서 이번장에서는!! 기본 저장장치 기술들을 살펴봅니다.

  • SRAM 메모리
  • DRAM 메모리
  • ROM 메모리
  • 회전 및 solid state 디스크

그리고 얘네가 어떻게 계층구조로 구성되는지 설명할거예요.

특히 CPU와 메인메모리 사이에 준비 영역으로 사용되는 캐시에 집중할 겁니다.

1장 저장장치 기술

컴퓨터 기술중에 대부분의 성공은 저장장치 기술의 엄청난 발전에 기인해요.

초기 컴퓨터는 그냥 몇 KB 의 데이터만 저장할 수 있었지만

지금은 거의 300,000배가 넘고

매 2년마다 2배씩 메모리 저장용량이 증가하고 있어요.

1.1장 랜덤-접근 메모리

랜덤 접근 메모리 ( RAM - Random Access Memory ) 는 두 종류를 가져요.

정적 램과 동적 램.

정적램 SRAM 은 캐시메모리로 사용되고 CPU 칩 내부 또는 외부에 장착되요.
동적램 DRAM 은 메인메모리와 그래픽 시스템의 프레임버퍼로 사용돼요.

일반적으로는

  • SRAM = 수십MB
  • DRAM = 수백~수천MB

를 갖게돼요.

이 이후의 내용을 읽기전에, SRAM은 캐시메모리, DRAM 은 메인메모리 그래픽 시스템의 버퍼로 사용된다고만 알고 있어도 1-1장은 충분해요.

정적 램 ( SRAM )

SRAM 은 각 비트를 이중안정 메모리 셀에 저장해요.

이게 뭐냐면. 우리가 비트에 0 혹은 1이라는 값을 저장했다고 해요.

이건 전기가 계속 공급되고 있는 상태여야 유지돼요. DRAM 은 64MS 초마다 전기적 충전을 해줘서 값을 유지하는데 이걸 Refresh라고 해요.

하지만 SRAM 처럼 이중안정 메모리 셀에 저장하면 전기적 충전 없이도 값이 유지돼요.

그래서 빠르고 신뢰성이 높아요.

근데 비싸요 ㅋ

보통은 이 이중안정 메모리를 진자에 비유하는데요.

끝에 무거운 추를 메단 진자가 있으면 왼쪽혹은 오른쪽으로 기울어져야 움직이지 않는 안정된 상태잖아요?
가운데에 서있으면 왼쪽으로 쓰러질지 오른쪽으로 쓰러질지 모르는 불안정한 상태예요.

그래서 SRAM 의 특징 하나 더는 살짝 충격이 있어도 원래 상태로 자동 복귀돼요.
전기적 잡음이나 빛 같은 외란에 대해 민감하지 않아요.

근데 DRAM 보다 트랜지스터 더 많이 쓰고 , 그래서 밀도가 더 낮고, 그래서 비싸고, 전기가 많이들어요.

동적 램 ( DRAM )

DRAM 은 각 비트를 전하로 캐패시터 라는 곳에 저장해요.

난 비전공자니까 캐패시터가 뭔진 몰라요.

근데 매우 작고, 각 셀은 캐패시터 하나와 접근 트랜지스터 하나로 구성돼요.

SRAM 과 달리 외란에 매우 민감하고, 캐패시터 전하가 달라지면 다시 회복할 수 없어요.

여러가지 원인의 전류누수가 dram 셀이 10~100밀리초 사이에 전하를 달라지게 해요.

그래서 주기적으로 메모리의 모든 비트를 읽었다가 다시 써주는 방식으로 Refresh해야해요.

일반 DRAM

DRAM 의 셀들은 d 슈퍼셀단위로 나눠지고, 또 각각의 d 슈퍼셀w DRAM셀들로 이뤄져요.

dxw DRAM비트의 정보를 저장해요.

이 슈퍼셀들은 Row와 Columns 로 이루어진 직사각형 배열로 구성되어 있어요.

그래서 슈퍼셀 [ i ][ j ] 를 읽으려면, 메모리컨트롤러가 행주소 i를 보내고 j를 보내요.

i 를 읽는 것을 RAS ( row access storbe ) 라고 하구요.
j 를 읽는 것을 CAS ( column access storbe ) 라고 해요.

그리고 i를 먼저 그림의 internal row buffer 에 복사하고.
그 internal row buffer 에서 j를 읽어요.

왜 이렇게 만들었을까요?
바로 주소핀수를 줄이기 위해서예요. 주소핀 수를 줄이면 뭐가 좋을까요?

  • 1. 칩 크기 줄어듦
    이렇게 만들면 제조비가 줄어들고 칩이 작아져요.
  • 2. 비용 절감
    핀 하나하나마다 배선,테스트,생산비용이 들기 때문에 전체 DRAM 생산비가 절감돼요.
  • 3. 패키징이 쉬워짐
    DRAM은 다른 부품들과도 함께 쓰이기 때문에 핀 수가 적을수록 다른 회로 설계가 용이해요.

메모리 모듈

컴퓨터 조립해보면 알겠지만 RAM 은 메인보드에 꽂을 수 있게 되어있어요.

이런식으로 각각의 RAM 들은 하나하나 모듈로 패키징되어서 출시돼요.

향상된 DRAM

DRAM 메모리는 여러 종류가 있고 규칙적으로 시장에 새로운 DRAM이 나오는데요.

그 종류를 알아볼게요.

기술특징
FPM DRAM같은 행에서 연속 접근 빠름
EDO DRAMFPM보다 더 빠름
SDRAM클럭 기반 동기식 접근
DDR SDRAM클럭의 양쪽 엣지를 활용하여 속도 2배
VRAM그래픽 전용, 읽기와 쓰기 동시 가능

뭐 이런 기술들이 있다 정도만 인지하고 넘어가셔도 될 것 같아요.

비 휘발성 메모리

DRAM과 SRAM은 전원이 꺼지면 정보도 사라져요.

그래서 휘발성 메모리입니다.

반면, 비 휘발성 메모리는 전원이 꺼져도 값이 유지돼요.

다양한 비 휘발성 메모리가 존재하고 , 일부는 읽기 뿐 아니라 쓰기도 가능하지만 여러이유로

  • 비 휘발성 메모리는 모두 ROM ( Read-Only-Memory ) 라고 불러요.
종류특징
PROM한 번만 프로그래밍 가능
EPROM자외선으로 초기화 후 재사용 가능
EEPROM전기적 방식으로 재기록 가능
FlashEEPROM 기반, 빠르고 널리 사용됨 (USB, SSD 등)

이런 ROM 들이 있습니다요.

메인 메모리 접근하기

메인 메모리에는 보통 DRAM 이 사용된다고 했는데요.

데이터는 버스라고 하는 전기회로를 통해서 프로세서(CPU)와 DRAM 간에 앞뒤로 교환돼요.

그래서 매 번 데이터의 전송은 버스 트랜잭션이라고 부르는 단계로 이뤄져요.

  • 읽기는 데이터를 DRAM -> CPU 로
  • 쓰기는 데이터를 CPU -> DRAM 으로 이동시켜요.

제어라인 들은 이 트랜잭션들이 어디로 가는지 어떤상태인지에 대한 정보를 관리해요.

버스가 많네요. 교대 환승센터인가? 하하하

1.2장 디스크 저장장치

하드디스크 같은 커다란 저장장치를 말해요.

디스크는 RAM 이 수천MB 를 저장할 수 있는거에 비해서

수백에서 수천기가바이트 단위까지 저장할수 있는 대표적인 저장장치예요.

근데 SRAM 보다 백만 배 더 오래걸리고, DRAM 보다 십만배 더 오래 걸림.

디스크들은 원판 ( Flatter ) 로 구성돼요.

원판의 중심에 있는 Spindle Motor 은 원판을 고정된 회전율로 회전시켜주고

보통 분당 5,400 번에서 15,000 번 정도 회전해요.

디스크 용량

디스크의 용량은 다음 요소들에 의해서 결정돼요.

  • 기록밀도 ( bits / in ) : 1인치의 트랙에 집어넣을 수 있는 비트의 수
  • 트랙밀도 ( tracks / in ) : 원판 중심에서 반지름의 1인치 길이에 넣을 수 있는 트랙의 수
  • 면적밀도 ( bits/in2) : 기록밀도와 트랙밀도의 곱

디스크 생산업체는 이 면적밀도를 높이기 위해서 쉼없이 노력하고 있고
매 몇 년 마다 2배로 늘어나고 있어요.

디스크의 동작

디스크는 위의 그림처럼 Actuator Arm 을 사용해서 데이터를 읽거나 써요.

드라이브는 팔의 반지름 방향의 축을 따라 헤드를 어떤 표면 위에도 위치시킬수 있는데 이걸 seek라고 합니다.

이 헤드는 약 0.1 마이크론 높이로 디스크 표면 위의 얇은 공기 쿠션을 시속 80km로 말 그대로 날아다니는데

디스크 위의 작은 먼지는 비유하면 거대한 바위와 같아요.

그래서 일반적으로 디스크들은 언제나 공기 밀폐 용기에 넣어서 밀봉해요.

디스크는 데이터를 섹터 크기의 블록으로 읽고 기록한다.

논리적 디스크 블록

운영체제는 디스크 섹터를 메인메모리로 읽어들이는 것 같은 입출력 연산을 수행하려 할 때,
디스크 컨트롤러로 명령을 보내서 특정 논리블록 번호를 읽어들이게 해요.

입출력 장치 연결하기

그래픽카드, 모니터, 마우스, 키보드, 디스크 같은 입출력 장치들은 입출력 버스로 CPU와 메인메모리에 연결돼요.

1.3 SSD ( Solid State Disk )

이 장에서는 SSD 가 위의 회전형 디스크에 비해 어떻게 다르고, 어떤 장점과 단점이 있는지, 성능과 수명에 어떤 영향을 미치는지 설명해요.

일단 SSD 는 HDD 보다 빠르지만 , 가격은 같은 메모리크기 기준 30배 비쌉니다.

SSD 는 HDD를 대체하는 매력적인 제품이예요.
기계적 부품이 없고 디스크대신 플래시 메모리 칩을 사용해요.
플래시 메모리 칩과 논리블록들에 대한 요청을 하부 물리 디바이스에 대한 접근으로 번역하는 플래시 번역 계층으로 이뤄져 있어요.

플래시 메모리는 저렇게

블록과 그 하부에 페이지들로 이뤄져 있어요.

  • 일반적으로 페이지는 512BYTE ~ 4KB 크기를 가지고
  • 블록은 32~128 의 페이지로 구성되며
  • 총 블록 크기는 16KB ~ 512KB 까지 가질 수 있어요.

데이터를 읽을 때는 페이지 단위로 읽고 써요.

한 개의 페이지는 자신이 속한 블록이 지워진 직후에 쓰일 수 있는데 이건 블록의 모든 비트가 1로 설정되는 것을 의미해요.

하나의 블록은 대략 10만번 정도 쓰이면 노후화되서 못써요.

이 표를 보면 랜덤 쓰기 작업이 랜덤 읽기 작업보다 느린데

  • 블록 단위 삭제 필요 → 페이지 쓰기 전 전체 블록 삭제 필요
  • 유효 데이터가 있는 다른 페이지는 복사 후 재배치해야 함 → 시간 증가

등의 이유로 랜덤 쓰기가 랜덤 읽기보다 빠를 가능성은 매우 낮아요.

1.4 저장장치 기술 동향

저장 기술의 저장용량은 늘었지만 속도는 크게 향상되지 않았어요.

DRAM 과 디스크 가격은 엄청나게 저렴해졌지만, 속도는 거의 그대로예요.

반대로 CPU 는 속도만 향상돼서 둘 사이의 병목이 더 커졌어요.

그나마 SRAM 이 유일하게 cpu 속도 향상과 비슷하게 따라가는 저장기술이예요.

그래서

SRAM <-> DRAM <-> SSD <-> 디스크

사이의 성능 차이를 계층적 구조로 설계해서

자주 쓰는 데이터를 상위 계층 (SRAM)에 배치하는 것이 핵심입니다.

2장. 지역성

잘 작성한 컴퓨터 프로그램은 좋은 지역성을 보여줘요.

지역성이란? 프로그램이 메모리를 접근하는 패턴의 규칙성을 말해요.
지역성이 좋은 프로그램은 최근 접근한 데이터나 그 근처의 데이터를 자주 다시 접근해요.

지역성에는 두가지 유형이 있어요. 하나는 시간적 지역성 (Temporal Locality)고 하나는 공간적 지역성 (spatial Locality) 예요.

  • 시간적 지역성은 최근에 참조된 데이터는 가까운 미래에도 다시 참조될 가능성이 높아요.
    => for루프 내에서 반복적으로 같은 변수를 사용할 때를 말해요.
  • 공간적 지역성은 한 번 접근된 데이터 주변의 데이터도 곧 접근될 가능성이 높단걸 의미해요.
    => 배열 순차 접근 arr[i] arr[i+1]... 을 의미해요.

지역성을 이해하고 있으면 이후에 나올 캐시구조 이해가 쉬워져요.

현대 시스템은 CPU 는 빠르지만 DRAM/디스크는 상대적으로 느리기 때문에 지역성이 없다면 병목현상이 심각해져요

캐시, 가상메모리, 디스크 버퍼 등 결국 모두 최근 접근 데이터만 빠르게 접근하려는 구조입니다.

2.1 프로그램 데이터의 지역참조성

간단한 C언어 코드를 살펴보면서 좋은 지역성과 나쁜 지역성을 보겠습니다.
Stride 는 보폭 이란 뜻인데요.

메모리를 0x00 에서 0x01로 가면 Stride-1 이라고 합니다.

int sumarrayrows(int a[M][N]) {
    for (i = 0; i < M; i++)
        for (j = 0; j < N; j++)
            sum += a[i][j];
}

c 는 row-major order로 배열을 저장해요.
배열을 0,0 0,1 0,2 순서대로 접근하고 있기 때문에 메모리상 연속됩니다.
Stried-1 이예요.
따라서 좋은 공간적 지역성을 가지고 있다고 볼 수 있어요.

int sumarraycols(int a[M][N]) {
    for (j = 0; j < N; j++)
        for (i = 0; i < M; i++)
            sum += a[i][j];
}

같은 코드인데 j와 i의 순서만 바뀌었어요.
배열을 0,0 1,0 2,0 순서로 접근하게 됩니다.
Stried-k 입니다. k는 배열의 크기에 따라 달라질거예요.
캐시 효율이 나쁘기 때문에 나쁜 공간적 지역성을 가지게 됐어요.

2.2 인스트럭션 선입의 지역성

인스트럭션(명령어)도 데이터처럼 지역성에 영향을 받는다는 개념입니다.

2.3 지역성 요약

앞서 설명한 개념들을 정리했습니다.

  • 동일한 변수들을 반복적으로 참조하는 프로그램은 좋은 지역성을 가진다.
  • Stried-k 참조 패턴을 갖는 프로그램에 대해서 k가 작을수록 좋다.
  • 루프는 인스트럭션 선입에 대해 좋은 시간 및 공간 지역성을 갖는다.

3장. 메모리 계층구조

이번 3장에서는 컴퓨터 메모리 시스템으 구조와 그것이 하드웨어와 소프트웨어의 지역성 특성과 어떻게 잘 맞물려 작동하는지를 설명해요.

저장장치 기술들은 매우 다양한 접근시간을 가지고 있고 , 빠를수록 비싸고 용량은 작아요.
느릴수록 싸고 용량은 커요.

그럼에도 불구하고 지역성이 좋고 계층적 메모리 구조를 잘짜면 빠르고 효율적인 실행을 할 수 있어요.

레벨구성 요소속도비용 (per byte)용량
L0CPU 레지스터매우 빠름 (1 cycle)매우 비쌈매우 작음
L1L1 캐시 (SRAM)빠름비쌈작음
L2L2 캐시 (SRAM)중간조금 비쌈보통
L3L3 캐시 (SRAM)느림보통
L4메인 메모리 (DRAM)훨씬 느림저렴훨씬 큼
L5로컬 디스크 (HDD/SSD)매우 느림매우 저렴수백 GB~TB
L6원격 저장소 (NFS, Web)가장 느림네트워크 비용 포함무제한

상위 계층은 하위 계층의 데이터를 캐시하는 역할이예요.
빠른 접근이 가능하도록요.

3.1 메모리 계층구조에서의 캐시

캐시 ( cache )더 느리고 큰 저장장치의 일부 데이터를 빠르고 작은 저장장치에 블록 단위로 복사해서 속도 향상을 꾀하는 구조예요.

이 과정을 캐싱이라고 합니다.

일반적으로 메모리 단위에서의 캐싱은 자동으로 동작하며, 프로그래머가 직접 신경 쓸 필요는 없어요.

캐시는 기본적으로 항상 블록 단위로 이동해요.
각 블록은 고유한 주소를 가지고 고정크기 혹은 가변크기일 수 있습니다.

캐시 적중 (hit)

어떤 프로그램이 레벨 K+1 로부터 데이터 data 를 필요로 할 때,
우선 K에 저장된 블록들 중 하나에서 data 를 찾아요.

어라? 있네 캐시히트~~ 라고 합니다.

캐시 미스 (miss)

반면, 만약 요청한 데이터가 캐시에 없을 경우에는 하위 계층에서 블록을 가져와요.
그리고 캐시에 있는 기존 블록을 교체합니다.

어떤 블록을 교체할지는 교체정책에 따라 정해지는데요.

  • 랜덤교체정책을 사용하면 랜덤으로.
  • LRU 교체정책을 갖는 캐시는 가장 과거에 접근한 블록을 선택할거예요.

캐시 미스의 종류

미스 종류설명
Cold miss (Compulsory miss)캐시가 비어 있어서 처음 불러올 때 발생
Conflict miss서로 다른 데이터가 같은 캐시 슬롯에 매핑되어 충돌 발생 (예: (i mod N) 방식)
Capacity miss작업에 필요한 데이터 양이 캐시 크기를 초과하여 계속 쫓겨남

레벨 K 의 캐시가 아예 비어있다면 , cold cache라고 불려요.

서로 다른데이터가 같은 블록을 계속 캐시하려고 하면 충돌이 나서 계속 블록을 교체해줘야 해요.
이걸 충돌미스 Conflict miss 라고 부릅니다.

무한루프 같은거 걸리면 Capacity miss나요.

캐시 관리

계층캐시 종류관리 주체
L0 (레지스터)4/8-byte 단어컴파일러
L1~L3 캐시64-byte 블록하드웨어
메인 메모리4KB 페이지OS + 하드웨어
디스크, 웹 캐시 등섹터/파일 조각OS, 디스크 컨트롤러, 웹 브라우저 등

다양한 저장장치의 캐시 관리주체는 다음과 같은데
이는 앞서 언급한 바와 같이 자동으로 동작하기 때문에, 프로그래머가 신경 쓸 필요는 없습니다.

3.2 메모리 계층구조 개념 요약

  1. 캐시가 잘 작동하는 이유는 지역성 때문이다.
  2. 캐시는 단지 CPU에서만 쓰이지 않고, 운영체제,네트워크,웹 브라우저 등 모든 곳에 존재한다.
  3. 시간 지역성과 공간 지역성을 잘 알고있자

4장. 캐시메모리

원래 과거 시스템의 메모리 계층구조는 단순했어요

레지스터 -> 메인메모리 -> 디스크

근데 CPU메인메모리간의 성능 차이가 커짐에 따라서 SRAM기반의 L1 캐시CPU메인메모리사이에 추가 됐어요.

캐시 계층위치접근 속도특징
L1 캐시CPU와 레지스터 사이약 4 사이클작고 빠름 (CPU 칩 안에 있음)
L2 캐시L1과 메인 메모리 사이약 10 사이클L1보다 크고 약간 느림
L3 캐시L2와 메인 메모리 사이약 50 사이클더 크지만 더 느림
메인 메모리가장 느림 (수백 사이클 이상)-DRAM 기반, 큰 용량

요즘 컴퓨터는 좀 더 많은 캐시메모리를 포함하고 있답니다?

4.1 기본 캐시 메모리 구조

캐시는 Set 으로 나뉘고 각 Set은 E개의 Line을 가져요.

각 Line 은 이렇게 구성돼요.

  • valid bit : 이 캐시 라인이 유효한 데이터인지?
  • tag bits : 이 라인이 어떤 주소를 대표하는지?
  • data block: 실제 데이터 크기

set 하나하나마다 valid 와 Tag를 가지고 있고
0, 1, 2......B-1 에는 블록 단위로 데이터가 저장돼 있어요.

주소 분할

메모리 주소가 A가 있어요. 우린 지금까지 그냥 0x00 으로만 써왔지만 메모리 주소는 원래 다음의 세 부분으로 나뉘어요.

구성 요소의미크기 (비트 수 32비트면 m = 32)
Tag (t)어떤 블록인지 구분t = m − (s + b)
Set Index (s)어떤 Set에 저장할건지s = log₂(S)
Block Offset (b)블록 내에서 몇 번째 바이트인지b = log₂(B)

즉, 주소 A로부터

  1. Set Index -> 해당 Set 선택
  2. Tag 비교 + valid bit 체크 -> 일치하는 Line 이 있는지 확인
  3. Block Offset -> 블록 내에서 실제 바이트 위치 결정

없으면 블록교체 해야겠지?

4.2 직접 매핑 캐시

직접 매핑 캐시는 Set 하나에 단 하나의 line ( E = 1 )만 저장하는 가장 단순한 캐시구조예요.

이거 왜 하냐면 이게 젤 허접이라 이해하기 쉬워서래요.

우리가 어떤 데이터를 가져올 때, 캐시 데이터가 있으면 캐시 적중! 없으면 캐시 미스! 잖아요.

이렇게 한 데이터를 뽑아내기 위해 수행하는 작업은 다음의 세 단계로 이루어져요.

(1) 집합 선택, (2) 라인 매칭, (3)데이터 추출

직접매핑 캐시에서 집합선택 ( Set Selection )

우선 요청주소 0xff1010이라고 할게요 그냥.
임의로 여기서 Set Index 를 추출해서 어느 Set을 사용할지 결정해요.

예: S = 2이면 2비트 -> 4개의 set (0~3번)

직접매핑 캐시에서 라인 매칭

선택한 set의 line이 유효(valid)하며 , Tag가 일치하면 hit.
아니면 miss -> 블록을 메모리에서 가져와 해당 line 에 저장.

직접매핑 캐시에서 데이터 선택

캐시 적중이 발생했을 경우예요.
요청주소 0xff1010에서 Block Offset을 사용해 block 내에서 원하는 데이터의 위치를 찾아요.

직접매핑 캐시에서 미스 발생 시 라인의 교체

어느 라인을 교체해야 할지 고민할 필요가 없다.
직접매핑은 정확히 한 개의 라인을 가지고 있으므로
현재 라인을 새롭게 선입한 라인으로 교체한다.

직접매핑 캐시에서 충돌미스

충돌미스는 실제 프로그램에서 일반적이고 어려운 성능문제를 야기해요.

직접매핑에서는 일반적으로 크기가 2의 제곱인 배열에 접근할 때 발생해요.

예를 들어서

1 float dotprod(float x[8], float y[8])
2 {
3 float sum = 0.0;
4 int i;
5
6 for (i = 0; i < 8; i++)
7 sum += x[i] * y[i];
8 return sum;
9 }

이 코드를 보면 2의 제곱인 8만큼의 크기를 가진 float 배열이 있어요.

float 이 4바이트고 x주소가 0부터 시작해서 32바이트의 주소값을 가질거예요.
float 이 4바이트고 y주소는 32부터 이어서 곧바로 시작한다고 가정할게요.

블록크기는 보통 BYTE 단위인데 ( 디스크 블록이랑 다른거임 ) 16B 라고 가정할게요.

하나의 블록은 4개의 float을 저장할 수 있네요.

요소주소Set index포함된 block (16B)포함된 요소들
x[0]000~15x[0] ~ x[3]
y[0]32032~47y[0] ~ y[3]
x[4]16116~31x[4] ~ x[7]
y[4]48148~63y[4] ~ y[7]

Set Index 계산법으로는 x[0]과 y[0] 이 계속 같은 set index 를 참조해서
계속 교체해줘야 해요.

그래서 이런 문제를 방지하기 위해 이렇게 코드를 짜기도 한대요 ㅋㅋ

float x[8];
float pad[4]; // 16 bytes 패딩
float y[8];

이거 진짜예요?

4.3 집합결합성 캐시

직접매핑 캐시에서 충돌문제는 딱 하나의 라인만 가진다는 제한에서 오는 거예요.

각 집합이 하나 이상의 캐시 라인을 가지는걸 집합결합성 캐시라고 해요.

집합결합성 캐시에서 집합의 선택

이건 직접매핑 캐시와 동일하게 주소 0xff1010에서 Set Index를 추출해서 사용해요.

집합결합성 캐시에서 라인 매칭과 데이터 선택

한 Set안에 여러개의 Line이 있으므로, 요청된 tag를 모든 Line 에 대해서 검사해요.

  • valid 비트 체크
  • tag 비교

집합결합성 캐시에서 미스

빈 line 이 있으면 그곳에 넣으면 돼요.
모든 line이 꽉차면? => 어떤 line 을 내보낼지 결정해야 해요.

라인교체정책:

정책설명
Random랜덤으로 하나 골라서 교체
LRU (Least Recently Used)가장 오래 전에 사용된 line을 교체
LFU (Least Frequently Used)과거에 사용 빈도가 가장 낮은 line 교체

4.4 완전결합성 캐시

완전결합성 캐시는

모든 캐시라인들을 갖는 하나의 집합으로 구성돼요.

완전결합성 캐시에서 집합선택

주소 0xff1010에서 Set Index를 찾을 필요가 없습니다.
그야 Set이 하나뿐인걸요?

완전결합성 캐시에서 라인매칭

집합결합성과 비슷하지만 모든 line 을 비교해요.
병렬로 tag 비교하구 , valid bit 확인합니다.

일치하면 block offset으로 확인!

4.5 쓰기와 관련된 이슈

지금까지 저 위에서 봤던건 전부 데이터 읽기와 관련된 글이였어요.
읽기는 단순해요. 캐시가 있으면 반환해주고 없으면 하위계층에서 찾아서 저장해요.

쓰기는 어떻게 처리할지 여러 전략이 존재해요.

쓰기 hit 처리방식

전략설명장점단점
Write-through즉시 하위 계층에 씀단순, 일관성 보장모든 쓰기에 버스 트래픽 발생 → 느림
Write-back캐시에서만 먼저 수정하고, 나중에 교체 시 하위 계층에 씀버스 트래픽 줄임 (지역성 이용)구현 복잡, dirty bit 필요

쓰기 miss 처리방식

전략설명장점단점
Write-allocate블록을 캐시에 불러온 후 수정지역성 활용 (향후 재사용 기대)miss 시 블록 전체 복사 필요
No-write-allocate캐시에 올리지 않고 하위 계층에 바로 씀구현 단순지역성 활용 X

기억 꿀팁
“Write-back은 캐시에 맡기고, Write-through는 메모리에 맡긴다.”
“Write-allocate는 불러오고 수정, No-write-allocate는 그냥 바로 써라.”

4.6 실제 캐시 계층구조의 해부

지금까지는 캐시가 오직 프로그램 데이터만을 보관한다고 가정해 왔는데요.
사실 캐시들은 데이터 뿐 아니라 명령어들도 저장할 수 있어요.

인스트럭션 "만" 보관하는 캐시는 i-cahce라고 불러요.
데이터 "만" 보관하는 캐시는 d-cache라고 불러요.
둘다 저장하는건 Unified cache라고 부릅니다.

현대 대부분의 CPU는 대부분 L1에서 i-cahced-cache를 구분해서 사용해요.

왜냐면

  • 병렬 처리 가능하고
  • 접근 패턴 최적화를 다르게 할 수 있고
  • 충돌을 회피할 수 있대요.

뭔소린지모름 걍 읽은 거 적음

레벨유형소유용도
L1 i-cache명령어 전용Core마다 개별빠른 instruction fetch
L1 d-cache데이터 전용Core마다 개별빠른 데이터 access
L2 cacheUnifiedCore마다 개별i-cache + d-cache 통합
L3 cacheUnified모든 코어가 공유크고 느림, 캐시 간 공유 데이터 역할

L3에서 공유하는 이유는 멀티코어 환경에서 데이터 공유할라고

4.7 캐시 매개변수의 성능에 대한 효과

캐시 성능은 보통 다음과 같은 지표로 확인해요.

용어설명
Miss rate전체 메모리 참조 중 캐시에 없는 비율 = #misses / #references
Hit rate히트 비율 = 1 - miss rate
Hit time캐시에서 데이터 가져오는 시간 (L1은 수 클럭 사이클 수준)
Miss penalty캐시 미스 후 하위 계층에서 데이터 가져오는 데 드는 추가 시간

캐쉬 크기의 영향

캐시를 크게 만들면 적중비율을 당연히 높여주겠죠.

근데 크기가 큰 메모리는 또 빠르게 동작하게 만들기 어려워요.

그 결과 크기가 큰 캐시는 적중하더라도 가져오는 시간이 길어져요.

그래서 캐시성능 지표중

hit rate 는 올라도 hit time 도 커져요. ( 속도가느려짐)

블록 크기의 영향

크기가 큰 블록들은 공간 지역성을 활용해서 적중 비율을 높여줄 수 있어요.

근데 같은 캐시 크기에서 라인 수가 감소해요. 왜냐하면 사이즈는 같은데 블록이 커지면 라인갯수가 줄어들 수밖에 없으니까요.

이건 시간지역성이 더 많은 프로그램에서는 적중 비율에 타격을 줄 수 있어요.

그리고 miss 가 났을 때 블록크기가 크니까 복사시간도 오래걸리게 돼요.

결합도의 영향

이건 집합당 라인수가 미치는 영향이예요.

라인수가 크면 미스가 줄어서 바꾸는 위험성을 감소시켜요.
근데 구현이 어렵고, 블록 크기의 영향과 마찬가지로 miss 되었을 때 교체비용이 많이들어요.

쓰기 전략의 영향

write-through 바로쓰기 전략은 간단하고 캐시와 메모리가 항상 같은 데이터를 갖고있어요.
구현도 쉽고 데이터를 메모리에서 바로 가져오기 때문에 write miss 에 특별히 복잡한 처리가 필요하지 않아요.

근데 모든 쓰기 동작이 바로 메모리까지 전달되기 때문에, 버스 사용량이 많아지고, 메모리 대역폭을 많이 차지해요.
쓰기 동작이 빈번한 경우는 메모리 접근이 많아져서 CPU가 기다리는 시간이 늘어날 수 있어요.

write-back 은 캐시안에만 저장하고 메모리에는 저장하지 않는 전략이예요.
메모리 접근 횟수가 감소하고 메모리 대역폭이 절약돼요.

단점은 복잡도가 증가하고 캐시와 메모리 사이에 데이터 차이가 존재해서, 멀티프로세서에서는 복잡한 동기화가 필요해요.

만약 캐시 블록이 여러번 변경됐어도 메모리에 반영이 늦어서 , 에러 발생시 데이터가 사라질 위험도 있어요.

0개의 댓글