본문 바로가기

High Level Technique/Window System

캐쉬와 가상메모리

캐쉬와 가상메모리


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
#include <stdio.h>
 
#define ARR_LEN 5
 
void bubblesort(int srcArr[], int n)
{
    int i, j, temp;
    
    for(i = 0; i < n; i++)
    {
        for(j=1; j < n-1; j++)
        {
            if(srcArr[j-1> srcArr[j])
            {
                temp = srcArr[j-1];
                srcArr[j-1= srcArr[j];
                srcArr[j] = temp;
            }
        }
    }
}
 
int main(void)
{
    int arr[ARR_LEN] = {53769};
    bubblesort(arr, ARR_LEN);
    
    for(int i = 0; i < ARR_LEN; i++)
    {
        printf("%d, ", arr[i]);
    }
 
    return 0;
}
cs



버블소트의 코드를 보면 선언된 지역변수들의 접근이 많이 이루어집니다. i, j, temp와 같은 변수들이요. 이러한 특성을 Temporal Locality라고 합니다.

라인 16을 보면 j값이 따라서 참조되는 메모리 영역이 4바이트씩 늘어나는데 해당 메모리의 영역 근처일 확률이 높을 때를 Spatial Locality라고 합니다.


위 두 특성이 일어나지 않도록 코드를 작성하면 캐시 메모리가 필요 없다고 생각할 수 있습니다. 하지만 진정한 개발자들은 캐쉬의 도움을 많이 받도록 구현을 한다고 합니다.

이러한 코드를 Cache Friendly Code라고 합니다.



캐쉬 알고리즘


CPU에는 ALU와 레지스터, L1캐쉬, L2캐쉬가 존재합니다. ALU에서 연산을 할 때 어디선가 데이터를 가져와 레지스터에 넣어줘야 합니다.


필요한 데이터가 0x1000번지에 존재한다면 해당 데이터를 레지스터로 가져오기 위해서 데이터가 존재하는 곳을 찾아야 합니다.


먼저 찾아보게 되는 곳이 L1캐쉬인데 해당 데이터가 존재할 경우 Cache Hit이 발생했다고 하고 없는 경우 Cache Miss가 발생했다고 합니다.


그렇다면 L1 캐쉬에도 없게되는 경우에는 어떻게 될까요? 마찬가지로 다음 캐쉬인 L2 캐쉬로 이동을 하게 됩니다. 


이때 데이터를 주고 받음에 있어서 정확히 해당 데이터만을 가져오는 것이 아니라 데이터 블록(영역) 단위로 데이터를 가져오게 됩니다.


앞서 말한 Spatial Locality 특성을 활용하는 것이죠.



또 하나는 데이터를 주고 받음에 있어서 데이터 블록 단위로 데이터를 가져온다고 했는데 L1 > L2 > RAM > 하드 디스크 순으로 갈 수록 더 큰 블록을 가져오게 됩니다.




L1 캐쉬가 가득찬 상태에서 데이터가 없어 L2 캐쉬에서 가져오게 될 경우에는 캐쉬 교체 정책에 의하여 가장 오래전에 참조된 블럭을 밀어 내 버립니다.





가상 메모리


메인 메모리는 1GB인데 어덯게 프로세스에 4GB를 할당해서 사용할 까요?



가령 16M의 메모리를 사용하는 환경이 있다고 한다면 물리 메모리 관점으로만 보자면 정확히 16MB의 메모리 안에서만 프로그램을 로딩하고 실행을 해야 합니다.


이는 너무 많은 제약사항이 생기게 됩니다.


그래서 존재하는 것이 가상 메모리 입니다.



32비트 시스템에서는 4GB 메모리를 할당 받을 수 있습니다. 메인 메모리가 64GB가 된다면 실질적으로 상관은 없겠으나 프로그램이 돌아가는게 한가지만 있는 것도 아니죠.


그래서 가상 메모리를 사용하게 됩니다. 


대부분 시스템에서 페이징 기법을 사용합니다. MMU (Memory Management Unit)가 1GB 밖에 안되는 메인 메모리를 4GB가 존재하는 것처럼 컨트롤을 해주는 것입니다.


MMU가 메모리 할당 단위에 따라서 요청이 들어오면 메인 메모리에 할당을 해주게 됩니다.


가령 메모리 할당 단위가 4MB인데 1MB만 필요한 경우에는 3MB가 남게 됩니다. 비효율 적일 수도 있지만 Spatial Locality를 생각하면 이해할 수 있습니다.



앞서 메모리 할당 단위라고 말했는데 하드웨어 입장에서는 이를 페이지 프레임이라고 하고 소프트웨어 입장에서는 페이지라고 합니다.




지금까지의 과정을 살펴보면 메모리 할당 단위(페이지)에 따라서 메인 메모리에 할당을 하고 MMU라는 녀석이 마치 물리적으로는 부족하지만 4GB가 있는 것처럼 컨트롤을 해준다.

라고 정리 할 수 있습니다.



그렇다면 할당을 모두 다 해서 메인 메모리에 가득찬 상태라면 어떻게 해야 할 까요?


이러한 문제를 해결하기 위해서 Swap File이라는 개념이 있습니다. 메모리 할당 단위에 따라서 메인 메모리에 데이터를 모두 할당할 경우 할당된 데이터 중 사용 확률이 낮은 데이터 영역을 하드 디스크에 옮겨줍니다. 그리고 다시 필요하다면 하드 디스크에서 가져오게 됩니다.




'High Level Technique > Window System' 카테고리의 다른 글

비동기 I/O (Asynchronous I/O)  (0) 2017.01.09
SEH (Structured Exception Handling)  (0) 2017.01.09
쓰레드 풀 (Thread Pool)  (0) 2017.01.04
생산자/소비자 모델  (1) 2017.01.04
쓰레드 동기화  (0) 2017.01.03