속성으로 공부하고 대충 게워내본 글입니다. 캐시 메모리를 해설하려고 했는데 어느 정도는 잘했지만 여전히 발전해야 할 것이 많습니다. 특히 캐시 메모리의 작동을 내부적인 관점에서 제가 직접 해설이 가능해야 하는데 지금은 아니네요. 일단은 대략적인 이해는 마쳤습니다. 글의 일부는 빠르게 타이핑하다보니 술어를 놀랍게도 반대로 타이핑하기도 해서 고쳤습니다. 참고가 되실 것 같습니다.
모든 컴퓨터 시스템은 프로세서와 메인 메모리의 구조를 가지고 있다. 프로세서가 임무를 수행하려면 프로그램을 메인 메모리에 적재해서 실행해야 한다. 프로그램 실행시 프로세서가 참조해야 하는 데이터를 메인 메모리에서 가져와서 처리한다. 그런데 프로세서의 속도보다 메인 메모리에서 참조하는 속도가 현저히 느려서 프로세서가 대기시간을 가지게 되어 처리 속도에 지장이 온다. 병목현상이 생긴다는 것인데 이를 방지하기 위해 개발된 기술이 캐시 메모리 기술이다.
캐시 메모리가 있는 시스템에서는 일단 메인 메모리에 적재된 정보를 캐시 메모리에 읽어들이고 프로세서는 이 캐시 메모리에 접근해서 처리하고, 그동안 메인 메모리의 다른 정보를 다시 캐시 메모리에 적재하고, 프로세서는 다시 캐시 메모리에 접근하는 방식으로 작동한다.
이렇게 하면 메인 메모리(DRAM)보다 빠른 소자로 된 캐시 메모리(SRAM)의 속도 이점을 받아 대기시간이 짧아지고 처리 속도가 향상된다.
캐시 메모리는 메인 메모리에 비해 제작 비용이 커져서 큰 용량을 장착하지 못한다.
대체로 아래와 같은 제한이 있다.
(1) 큰 용량을 장착하려면 비용이 든다
(2) 프로세서 다이 안에 두는 경우 미세공정의 발전이 따라와야 한다
(3) 캐시 메모리를 참조하는 알고리즘의 한계로 무작정 크게 만들 수가 없다
(4) 메인 메모리와 같은 크기의 캐시라면 히트율이 늘 100이지만 비효율적이다
그래서 현대적인 프로세서들은 L1, L2, L3로 차등을 두어 캐시 메모리를 운용한다. L1이 제일 빠르고 용량이 작고, L3가 제일 느리고 용량이 크다.
캐시 메모리 참조시에 원하는 정보가 캐시 메모리에 있으면 캐시 적중(캐시 하트, cache hit), 없으면 캐시 실패(캐시 미스, cache miss)라고 한다. 캐시 적중을 높히도록 해결하려면 여러 개의 정보를 캐시에 될 수 있는 한 많은 개수를 저장해두면 해결되는 경우가 있다. 이로부터 캐시 메모리의 크기를 키워서 용량을 늘리기도 하는데 제작 비용의 문제도 그렇고 위에 언급한대로 무한정 크게 할 수가 없게 된다. (4)처럼 될 수 있다.
캐시 메모리의 사용으로 프로그램 처리 속도가 높아지는 것은 지역성의 원리로 인해서다. 지역성은 시간 지역성과 공간 지역성으로 분류된다.
시간 지역성은 한 정보가 참조되면 빠른 시간 안에 다시 참조되는 경우이다. 메인 메모리의 접근 시간이 100ns이고 캐시의 접근 시간이 25ns라면 메인 메모리에서 정보를 가져올때는 100ns가 걸리고 캐시에서 가져오면 25ns다. 이를 루프를 10번 돌린다고 할때 1000ns vs 250ns의 차이가 있게 된다. 혹시라도 1회 정도 캐시 실패가 일어나서 메인 메모리를 참조해도 325ns다. 루프를 10번 돌린다는 것은 시간 지역성이 고려되어야 하는 상황이다.
반면 공간 지역성은 한 정보가 참조되면 다른 이웃 정보도 참조되는 경우이다. 루프를 돌릴때 코드에서 이웃한 다수의 정보를 연속해서 캐시 메모리로 옮길 경우 예컨데 코드에서 쓰인 4개의 정보를 캐시로 옮겨 처리하면 공간 지역성과 같은 이점이 있게 된다. 메인 메모리에서 읽으면 100ns 곱하기 4로 400ns가 소요되고, 캐시에서 읽으면 25ns 곱하기 4로 100ns가 소요된다. 이는 공간 지역성의 원리로 처리 속도가 향상된 것이다.
캐시에서 블록의 크기를 정하는 것도 설계의 관점에서 유효하다.
블록은 캐시 실패가 발생시 주기억장치에서 캐시로 복사하는 정보 단위다. 캐시의 크기가 256바이트일때 블록이 16바이트면, 캐시 내 블록개수는 16이다. (256/16) 블록의 크기가 32바이트라면, 블록의 개수는 8이다 (256/32)
블록 크기는 히트율을 높히도록 결정해야 한다. 블록 크기가 작아지면 블록 개수가 많아진다. 이 경우 블록 개수가 많아져서 시간 지역성이 좋아지지만, 블록 크기가 작아져서 공간 지역성이 나빠진다. 반대로 블록 크기가 커지면 블록 개수가 적어진다. 이 경우 블록 크기가 커지기 때문에 공간 지역성은 좋아지는 반면 시간 지역성은 나빠지게 된다.
캐시 적중을 높히려면 블록을 캐시에 사상하는 방법도 유의된다. 직접 사상 방법과 완전 연관 방법, 세트 연관 방법이 대표적이다.
직접 사상 방법은 캐시 실패 발생시 블록이 복사될 수 있는 캐시 블록은 한개로 고정된다.
완전 연관 방법을 쓰면 캐시 내 모든 블록에 복사될 수 있다.
이 두 방법을 절충해서 세트 연관 방법이 쓰인다.
직접 사상을 한다면 메인 메모리 블록 번호가 00100, 01100, 10100, 11100일때 하위 3비트가 100이므로 캐시 블록 번호 100에 사상된다.
직접 사상의 동작 과정은 저본에 의하면
(a) CPU가 주소 010100000을 생성하여 캐시 메모리에 데이터를 요청한다
(b) 캐시 메모리는 주소를 CPU 태그 01, 인덱스 010, 블록 오프셋 0000으로 분할한다
(c) 인덱스 필드 010이 가리키는 캐시 메모리의 태그를 추출한다
(d) CPU 태그와 캐시 태그를 비교한다
(e) 캐시 메모리가 초기 상태이므로 유효 비트가 0이다. 따라서 CPU에 캐시 실패라고 알린다
(f) CPU는 메모리에 동일한 주소를 보내어 데이터를 요청한다
(g) 데이터 a가 있는 메모리 블록 01010을 복사하여 캐시 메모리로 전송한다
(h) 메모리 블록을 인덱스 필드 010이 지시하는 캐시 블록으로 사상하고 캐시 태그를 01로 갱신한다
(i) 블록 오프셋 0000을 이용하여 캐시 블록에서 데이터 a를 추출하고 CPU에 전송한다만약 직접 사상 방식에서 예제 컴퓨터가 워드 주소 010100100에 있는 데이터 b를 참조할때라면
(ㄱ), (ㄴ), (ㄷ), (ㄹ) 데이터 a를 참조할 때와 동일한 방식으로 실행
(ㅁ) 유효 비트가 1이며 두 태그가 일치하므로 캐시 적중이다
(ㅂ) 블록 오프셋 100을 사용하여 캐시 블록에서 데이터 b를 추출하고 CPU에 전송한다직접 사상 방식에서 워드 주소 000100000에 있는 데이터 e를 참조할때는 데이터 a의 블록과 충돌한다. 데이터 a와 e를 가진 블록은 메모리 블록 주소에서 하위 3비트가 동일하기 때문이다.
이보다 더 자세한 실행 순서는 우종정 교수님이 저술하신 “컴퓨터 아키텍처 컴퓨터 구조 및 동작 원리”를 참고하세요. 전에 소개한 여섯권의 책 중에서 캐시 메모리 해설이 제일 좋네요.
위에 지역성 설명에서 루프문을 예로 들었는데 정확히 말하자면 for 루프인 경우 인덱스로 쓰인 i 변수가 여러번 참조되는게 시간지역성이고 for 루프 내부에 변수로 쓰인 변수들이 참조되는게 공간지역성이네요. 시간지역성은 부분접근이 자주 되는 경우 즉 캐시 메모리 구조에서 같은 부분이 여러번 접근될때의 속도를 말하고 공간지역성은 서로 다른 변수가 루프에 의해 인접된 데이터 위치가 자주 접근되는 경우를 말합니다. 보충해둡니다.