컴퓨터 프로그램의 동작과정을 생각해보자. 아주 간단하게 생각해보자면 프로세스로 바뀐 프로그램은 메모리(RAM)으로 올라가서 CPU에 의해 실행된다. 작업 과정에서 CPU는 작업에 필요한 정보들을 불러와야 한다. 이러한 정보들은 프로그램이 저장되어 있는 저장소(HDD, SSD)에 저장이 되어있다. 작업을 할 때마다 저장소에서 정보를 불러온다면 어떤 일이 일어날까? 사실 프로그램 실행에 있어서는 아무 문제가 되지 않을 것이다. 그러나 반복 작업에 있어서 정보를 불러오는 작업을 계속한다면 매우 오래 걸릴 것이다. 이를 해결하기 위해 자주 사용하는 데이터는 캐시(Cache)라는 공간에 저장하여 빠르게 불러오는 것이다.

 

 캐시(Cache)는 CPU와 메모리 사이에 존재하는 작은 저장공간이다. 속도가 빠른 메모리를 사용하기도 하고, 물리적으로 가까이 붙어있어서 저장공간에서 불러오는 것에 비해 빠르다. 보통 L1, L2 등 캐시를 분류하기도 한다. 더 빠르고, 더 가까이 있는 차이다. 다른 블로그에서 본 글인데, L1은 CPU의 코어마다 할당되어 IL1(Instructure), DL1(Data)으로 분류된다고 한다. L2는 모든 코어가 공유하는 데이터가 들어간다고 한다. 


Cache Hit / Cache Miss

CPU는 작업을 하며 정보가 필요할 때 캐시(Cache)에서 원하는 정보가 있는지 찾아본다. 이때 원하는 정보가 존재하여 바로 가져오는 상황을 Cache Hit라고 하며, 정보가 없어서 저장소에서 찾는 상황을 Cache Miss라고 한다. 


 Locality

 지역성은 데이터의 모든 부분을 균일하게 참조하는 것이 아닌 특정 부분을 집중하여 참조하는 특성이다. 캐시(Cache)에는 2가지 지역성이 있다. Temporal Locality와 Spatical Locality이다. Temporal Locality는 최근에 사용되었던 데이터는 다음에도 사용될 것이라고 가정하는 것이다. 따라서 한 번이라도 사용된 데이터는 캐시에 저장해놓는다. Spatical Locality는 최근에 사용된 데이터의 주변 데이터도 사용될 것이라고 가정하는 것이다. 

 

 코드로 예시를 들어보겠다. 

 

int[10000][10000] arr = new int[10000, 10000];

for (int i = 0; i < 10000; i++) {
	for (int j = 0; j < 10000; j++) {
    		arr[i, j] = 1;
    	}
}

for (int i = 0; i < 10000; i++) {
	for (int j = 0; j < 10000; j++) {
    		arr[j, i] = 1;
    	}
}

 

 위 코드에서 반복문을 보면 배열에 접근하는 순서가 다르다. [i, j] 와 [j, i]의 차이이다. 반복되는 횟수는 동일하다. 어느 반복문이 더 빨리 실행될까? 정답은 위의 반복문이 더 빠르다. 그 이유에는 메모리의 구조와 캐시 지역성의 영향이 있다. 메모리의 구조는 아래 코드 블럭을 보면 [i, j]로 접근 후, [i, j+1]에 접근하는 순서로 진행하게 된다. 이때 주변 메모리의 값도 미리 가져오는 Spatical Locality에 의해 미리 배열의 값을 캐시에 저장하였기 때문에 빠르게 처리할 수 있었던 것이다.

 

[0, 0][0, 1][0, 2][0, 3][0, 4] / [1, 0][1, 1][1, 2][...][] / [][][][][] / [][][][][]...

 


 캐시(Cache)는 단일 스레드 환경에서는 정상적으로 작동을 잘 하지만, 멀티 스레드 환경에서는 코어마다 들고 있는 캐시 값이 서로 맞지 않는 상황이 발생할 수도 있다. 이후 프로그래밍을 할 때, 이 문제를 해결할 방법들을 공부할 예정이다.

'OS' 카테고리의 다른 글

OS - Lock, InterLocked - C#  (0) 2024.07.15
OS - 메모리 배리어 - Memory Barrier  (0) 2024.07.11
OS - 컴파일러 최적화  (0) 2024.07.09
OS - 스레드 생성(Task) - C#  (0) 2024.07.08
OS - 스레드 생성(Thread, ThreadPool) - C#  (0) 2024.07.08

+ Recent posts