캐시Cache의 Spatial Locality
이번에는 캐시에 대해서 간단히 실습해보겠습니다. 물론 캐시에 대해 아는 것도 멀티쓰레드 프로그래밍과 관련이 있습니다. 멀티쓰레드 프로그래밍에서는 코드가 캐시를 얼마나 효율적으로 잘 사용하는지 여부에 따라서 그 성능의 차이가 싱글쓰레드 프로그래밍보다 커진다고 합니다. 그렇다면 캐시란 무엇일까요? 지난 포스팅에서 소개했던 AMD사의 CPU를 다시 보겠습니다.
76MB의** L2+L3캐시**가 있다고 소개하고 있습니다.
캐시는 CPU가 가지고 있는 메모리인데, 우리가 일반적으로 더 잘 접해왔던 컴퓨터의 메모리부품(RAM)의 역할을 CPU에서도 일부분 맡고 있는데 그 부품을 캐시라고 합니다. 그 용량이 매우 적어서 별도의 RAM 부품은 당연히 대체할 수 없지만 도대체 왜 필요할까요? 캐시가 필요한 이유는 컴퓨터에서 CPU와 RAM의 물리적인 거리가 있기 때문입니다. 와닿게 하기 위해서 사진을 보여드리겠습니다. 아래 사진은 컴퓨터에서 CPU와 RAM이 체결되는 메인보드입니다. 두 부품이 물리적으로 구별되는 부품이므로 거리가 존재할 수 밖에 없습니다.
그래서 모든 데이터를 다 RAM으로 옮겨서 기억하도록 하게 하기보다는, 잠깐 동안만 기억하면 좋을 정보는 RAM까지 전달할 필요 없이 CPU내에서 단기간 동안만 기억하도록 한다면 더 좋은 성능을 가질 수 있습니다.
캐시가 동작하는 원리에는 두 가지 원리가 있다고 합니다.
- 방금 처리한 정보와 시간적으로 가까운 정보는 캐시에 저장한다. (Temporal Locality)
- 방금 처리한 정보와 공간적으로 가까운 정보는 캐시에 저장한다. (Spatial Locality)
그러면 이제 Temporal Locality를 고려해서 캐시가 잘 사용되도록 코딩을 해보고, 그렇지 않은 경우와 비교를 해봅시다.
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
36
37
38
39
40
41
using System;
using System.Data;
using System.Threading;
namespace ServerCore
{
internal class Program
{
static void Main(string[] args)
{
int[,] arr = new int[10000, 10000];
{
// 10000 * 10000 배열
// [첫번째][두번째][세번째][네번째]...10000개 [][][][]...10000개 [][][][]...10000개 ...
// 인접해 있는 데이터에 접근할 때는 캐시로 처리하기 때문에 빠르다.
long now = 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 - now}");
}
{
// 10000 * 10000 배열
// [첫번째][][][]...10000개 [두번째][][][]...10000개 [세번째][][][]...10000개 [네번째][][][]...10000개...
// 인접하지 않은 데이터에 접근하므로 방금 전 예시보다 캐시를 덜 사용하여서 덜 빠르다.
long now = 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 - now}");
}
}
}
}
결과는 어떤가요? 첫 번째 경우가 더 빠른 것을 볼 수 있습니다. 그 이유는 첫 번째 경우는 배열에 접근할 때 가깝게 위치한 정보에 접근하기 때문입니다. 가까운 정보는 캐시에 저장되어 있었어서 더 빠르게 로드한 것입니다. 멀티쓰레드 프로그래밍에서는 이러한 차이가 더 커질 수 있다고 합니다.
이 글은 인프런의 '[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버' '캐시 이론' 강의를 참고하여 정리 목적으로 작성하였습니다. 감사합니다.



