Home 7강 캐시 이론
Post
Cancel

7강 캐시 이론

7강 캐시 이론

[1] 캐시란 무엇일까

[1]

스토리텔링

상황

🍴 레스토랑에서 주문을 받음

🔖 주문 현황이 적힌 스크립트가 주방에 들어가면 주문이 접수되는 구조

🧑🧑‍🦰 주문을 받는 식당 직원이 여러 명인 상황

🧑식당 직원1이 사이다를 주문받았고, 이 사람이 다른 일을 하러가는 도중에

같은 테이블에서 🧑‍🦰식당 직원2에게 사이다 말고 콜라로 바꿔달라는 주문을 넣었다!

이때 주문 현황 판에 한번에 많이 쓰는 것이 효율적이므로,

식당 직원이 기억해서 📘 미니 수첩에 적고,⇒ 이를 나중에 🔖 주문 현황에 업데이트 하는 구조가 됨

🧑‍🦰 曰 : “예? 주문 현황이랑 제 수첩에는 사이다 주문에 대한 얘기는 아무것도 없는데요 …”

⇒ 🧑 🧑‍🦰 주문을 받는 식당 직원이 여러 명인 탓에 혼란이 일어난다 !

[2] CPU의 구조

CPU는 코어로 구성됨

  • 코어의 구성 :
    1. ALU : 연산장치
    2. 캐시장치 : 기억장치

식당 직원들이 🔖 주문현황을 업데이트 하기위해 개인 수첩들을 사용하는 것처럼

  • 📘 미니수첩 = 레지스터, L1 캐시, L2 캐시 등의 기억장치들이 있다
  • 🔖 주문현황 = RAM (기억 메모리)

[2] 캐시의 철학

캐시는 다음과 같은 철학을 바탕으로 만들어졌다

[1] Temporal Locality

시간적으로 보면, 방금 최신 주문한 테이블에서 추가 주문이 나올 확률이 높다

⇒ 최신 주문을 메모해 놓으면 편할 것이다

  • (추가) 주문 = (재) 사용
[2] Spacial Locality

공간적으로 보면, 방근 주문한 사람 근처에 있는 사람이 추가 주문할 확률이 높다

⇒ 최신 주문한 사람과 합석하는 사람들의 주문들도 메모해놓으면 편할 것이다

  • (추가) 주문 = (재) 사용

[3] 멀티 스레드 환경의 문제

직원이 여러명일 시 문제

이 스토리텔링은 멀티 스레드 환경의 문제를 나타내는데, 이는 다음과 같음

⇒ 어떤 값이 있고, 멀티스레드 환경일 때

CPU마다 🧑코어가 있고 각각의 📘캐시가 존재할 것임.

코드 상에서 내가 🧑스레드에서 어떤 값을 바꿨다고 해도 멀티스레드 이기 때문에

100% 확률로 바뀐 값이 🔖메모리에 올라가는 것이 아니라,

🧑‍🦰 입장에서는 바뀌지 않은 구버전의 값을 🔖메모리에 올려버릴 수도 있는 것임

[4] 캐시의 작동

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
static void Main(string[] args)
				{

            //캐시의 작동을 확인하기
            //결과 :
            //(y,x) 순서 걸린시간 : 2196603
            //(x, y) 순서 걸린시간: 3814860
            int[,] arr = new int[10000, 10000];

            {
                long start = DateTime.Now.Ticks; //시작 시간 알아보기
                // [][][][][] ... 메모리 상 인접한 순으로 열 -> 행 으로 진행
                for (int y = 0; y < 10000; y++)
                {
                    for (int x = 0; x < 10000; x++)
                        arr[y, x] = 1;
                }

                long end = DateTime.Now.Ticks; //끝난 시간 알아보기
                Console.WriteLine($"(y,x) 순서 걸린시간 : {end - start}");
            }
            { //스코프 나누기
                // []       []        []       [] ... 이 순서로 행-> 열 순서로 진행 메모리상 인접하지 않은 순서로 진행
                long start = DateTime.Now.Ticks; //시작 시간 알아보기
                for (int y = 0; y < 10000; y++)
                {
                    for (int x = 0; x < 10000; x++)
                        arr[x, y] = 1;
                }

                long end = DateTime.Now.Ticks; //끝난 시간 알아보기
                Console.WriteLine($"(x,y) 순서 걸린시간 : {end - start}");
            }

        }
  1. 전역 변수로 2차배열 선언
  2. 같은 횟수의 반복문 사용하여 2차배열에 값 넣기
  3. 같은 횟수의 반복문 사용하여 2차배열에 값 넣기
  • 스코프를 { }로 나눠서 같은 이름의 변수 사용 가능하게 만듦
  • DateTime.Now.Ticks; 의 start와 end를 빼서 ⇒ 걸리는 시간을 추출
  • new int[10000, 10000] : 어마어마하게 큰 크기의 2차배열
  • 2중 반복문에서 각각 y,x 순서만 다르게 값을 1로 초기화

결과)

1
2
(y,x) 순서 걸린시간 : 2196603
(x,y) 순서 걸린시간 : 3814860
  • 거의 2배 차이!

⁉️ 😒

왜 두 경우가 같은 시간이 걸리지 않은걸까?

이렇게 나오게 된 이유 :

(y,x) 순서로 열 ⇒ 행 으로 진행하는 것이

메모리 공간 상 인접한 곳에 있는 정보를 등록해놓는

캐시의 이점을 활용했기 때문에 더 빠르다 ✨

  • 2차 배열은 메모리 공간 상

1행: [][][][][][] 2행: [][][][][][] 3행: [][][][][][] … 이런 식으로

존재 &접근

  • (x.y) 순서의 행⇒열 접근은

메모리 공간 상 띄엄띄엄 있는 곳을 접근했기 때문에 캐시의 이점을 활용하지 못했다

1행: [][][][][][] 2행: [][][][][][] 3행: [][][][][][] 이런 식으로 존재

1행: [] … 2행: [] … 3행: [] … 이런 식으로 접근

This post is licensed under CC BY 4.0 by the author.