[스터디] 시스템 프로그래밍 - Chapter 16. 컴퓨터 구조의 4번째 이야기

2023. 11. 28. 23:08·독서/뇌를 자극하는 윈도우즈 시스템 프로그래밍

뇌를 자극하는 윈도우즈 시스템 프로그래밍(저자, 윤성우)


보통 컴퓨터 부품 중에서 메모리라고 한다면, 램을 생각하기 쉽다. 하지만, 램 말고도 메모리라고 불릴 수 있는 요소들은 다양하게 있다. 이는 다음과 같다.

 

- 메인 메모리 :

D램 계열의 메모리인 램이다. 참고로 모든 메인 메모리가 램을 뜻하는 것은 아니다. 하지만 대부분의 컴퓨터가 메인 메모리로 램을 사용하고 있으므로, 동일한 의미로 작성한다.

 

- 레지스터 : 

CPU 안에 내장되어 연산을 위한 저장소를 제공한다.

 

- 캐쉬 : 

캐쉬는 D램보다 빠른 S램으로 구성한다. CPU와 램 사이에서 중간 저장소 역할을 하는 메모리다. 종종, CPU 안에 캐쉬가 내장되어 있다고 표현되어 있으나, CPU에 근접한 메모리 개념이지, CPU의 일부로 존재하는 개념이 아니다.

 

- 하드 디스크와 이외의 저장 장치들 :

하드 디스크도 역시 메모리다. 이외로도 SD 카드, CD-ROM과 같은 I/O 장치들도 메모리에 해당한다.


01. 메모리 계층Memory Hierachy

프로그램이 실행되는 동안에 메모리의 역할은 데이터의 입력/출력이다. 이는 CPU에 위치한 물리적 거리에 따라서 달라지는데, 레지스터, 캐쉬 메모리, 메인 메모리, 하드 디스크 순으로 CPU에서 멀리 있다.

 

CPU와 가까이 있으면 빠르고 멀면 느리다. 어려운 것 없이 가까우니까 빠른 것이다. 물론, 메인 메모리와 같이 Bus 인터페이스 컨트롤을 통하여 사용하는 것은 별개의 사유가 있을 수 있다.

 

메모리는 다음과 같은 피라미드 계층 구조를 지닌다.

레지스터 -> L1 캐쉬 -> L2 캐쉬 -> 메인 메모리 -> 하드 디스크

 

메모리는 자신의 바로 아랫단계, 혹은 윗단계에 있는 메모리들에게 자신의 데이터를 전달한다. 레지스터는 L1 캐쉬에게 L1캐쉬는 L2캐쉬, L2캐쉬는 메인 메모리, 마지막에는 하드 디스크로 전달이 되고 반대의 경우에는 역순을 진행된다.

 

하드 디스크에서 읽는 데이터를 처리하기 위해서 바로 레지스터로 접근하는 것이 아닌, 중간 과정을 거치게 된다. 데이터의 이동이 심히 많다고 생각할 수 있지만, 이는 메인 메모리를 제외한 L1 캐쉬와 L2 캐쉬에 연산에 필요한 데이터가 존재할 확률이 높기 때문에 캐쉬는 생각보다 높은 성능 향상을 가져다준다.

 

▶ Level1 캐쉬와 Level2 캐쉬

: 컴퓨터에서 캐쉬를 말할 때, L1 캐쉬와 L2 캐쉬라는 용어를 사용한다. 1차 캐쉬와 2차 캐쉬라고도 한다. L1 캐쉬는 CPU 내부가 아니라 시스템 보드(메인 보드)에 존재하는 메모리였으나, 성능 향상을 위해서 CPU 내부에 들어가게 되었고 CPU 외부에는 새로운 캐쉬, L2 캐쉬가 등장했다.

시스템의 성능을 좌우하는 클럭 속도는 느린 쪽에 맞춰진다. 기술의 발전으로 CPU 역시, 발전했으나 메인 메모리의 처리 속도를 따라가지 못한다. CPU가 연산을 하기 위해서 메인 메모리에서 피연산자에 해당하는 데이터를 가져와야 하고, 그 연산 결과를 메모리에 저장한 다음에야 다음 작업을 할 수 있다.

즉, 데이터 입력 및 출력에 엄청난 시간을 소비하게 된다는 것이다.

따라서 자주 사용되는 주소 번지의 데이터는 캐쉬 메모리에 저장해 둬서 메인 메모리까지 가는 빈도 수를 줄일 수 있다. CPU는 1Ghz로 동작한다고 가정하자. 특정 연산을 하는 데 있어서 필요한 데이터가 캐쉬 메모리에 있다면, 그 연산은 1Ghz로 처리될 것이다. 그러나, 메인 메모리에서 가져오게 될 경우 0.2Ghz(가정)로 동작하는 메모리가 데이터를 전달할 때 까지 CPU는 쉬고 있어야 한다.

이러한 부분은 병목 현상의 원인이 된다. 병목 현상을 최소화하기 위해서는 제약이 있는 캐쉬 용량의 증가라는 방법보다, 캐쉬를 하나 더 두면 된다. 이렇게 하면 병목현상의 주체가 L1 캐쉬로 L2 캐쉬로 이동했다. L2 캐쉬는 CPU 내에 존재하므로 메인 메모리보다 접근이 빠른 구성을 가진다. 또, L1 캐쉬에 비해서 크기가 크기 때문에 필요로 하는 데이터를 훨씬 더 많이 저장할 수 있다.

02. 캐쉬Cache와 캐쉬 알고리즘

템퍼럴 로컬리티Temporal Locality는 자주 접근하게 된다는 프로그램 특성을 표현할 때 사용하는 말이다. 또, 스페이셜 로컬리티Spatial Locality는 프로그램 실행 시 접근하는 메모리 영역은 이미 접근이 이루어진 영역의 근처일 확률이 높다는 프로그램 성격을 표현할 때 사용하는 말이다.

 

소프트웨어의 이러한 두 가지 특성 때문에 캐쉬는 성능 향상에 많은 도움이 된다. 이렇게 구현된 코드를 캐쉬 프렌들리 코드Cache Friendly Code라고 한다. 캐쉬의 도움을 받지 못하도록 프로그램을 구현할 수 도 있긴 하지만, 추천하는 방식은 아니다.


02.A. 캐쉬 알고리즘

ALU 연산 과정 중에서 필요한 데이터가 있다면, 이를 레지스터로 이동시켜야 한다. 만약, L1 캐쉬에 데이터가 있다면 이를 가리켜 캐쉬 힛Cache Hit이 발생했다고 하며, 해당 데이터를 레지스터로 이동시킨다. 반대로 존재하지 않을 경우에는 캐쉬 미스Cache Miss가 발생했다고 하며, L2 캐쉬로 이동해서 데이터를 가져온다. 없을 경우에는 메인 메모리로 이동하여 가져온다.

 

이때, 데이터의 이동은 블록 단위로 스페이셜 로컬리티의 특성을 살려 전달된다. 

▶ 물리적 거리에 따른 용량 차이

: L1 캐쉬 -> L2 캐쉬 -> 메인 메모리의 용량은 후순위로 접촉하는 메모리일 수록 많은 용량을 보유하고 있다. 이는 후순위의 메모리일수록 속도가 느리기 때문에 접근 횟수를 줄이는 것이 성능 향상에 도움이 되기 때문이다.
▶ 캐쉬 교체 정책Cache's Repleacement Policy

: 캐쉬 메모리가 채워져있어야 원하는 데이터를 가져올 확률이 높기 때문에 캐쉬 메모리를 비워두지 않는 것이 좋다. 캐쉬 미스가 발생해서 L2 캐쉬로부터 L1 캐쉬로 데이터 블록을 읽어 들일 때, 어느 곳에 저장해야 할 지 문제가 생긴다.

공간이 없는 L1 캐쉬에서 데이터를 저장하기 위해서 기존에 저장된 데이터를 밀어내야만 하는데, 이는 캐쉬 교체 정책에 따라서 달라진다. 이 중에서 대학 수업에서 보편적으로 거론되는 LRU(Least-Recently Used) 알고리즘이 있는데, 이름대로 가장 오래 전에 참조된 블록을 밀어내는 알고리즘이다.

03. 가상 메모리Virtual Memory


03.A. 물리 주소Physical Address

용량이 16MB인 램이 있다고 가정하자. 그러면 접근 가능한 메모리 주소는 0번지부터 16x1024x1024 - 1번지 사이가 된다. 이것은 실제 물리적인 메인 메모리의 주소 범위에 해당하며, 이렇게 주소를 할당하는 것을 가리켜 물리적 주소 지정Physical Addressing이라 한다. 이 경우, CPU 입장에서는 접근 가능한 주소 범위가 제한된다. 


03.B. 가상 주소Virtual Address 시스템 1

가상의 주소를 지정하는 것을 가상 주소 지정Virtual Addressing이라 하며, 가상 주소 지정을 통해 할당 받는 공간을 가상 메모리 공간Virtual Address Space이라고 한다. 메모리 공간에 비해서 많은 용량을 사용할 수 있는 이유는 하드 디스크의 일부 공간에 메모리의 역할을 맡겼기 때문이다. 

 

비록 느린 편이나, 아래 2가지 문제를 고려한다면 문제가 될 것은 없다.

 

1. 선 할당으로 인한 부담

2. 느린 속도의 개선 필요성

 

가상 메모리 시스템을 구현하는 방법에 대해서는 표준으로 정해진 것은 없으나, 대부분 페이징Paging이라는 기법을 사용한다.  페이징 알고리즘을 살펴보기 위해서 아래의 가정을 가져보자.

 

가정 1. 16비트 시스템, 따라서 0부터 64KB - 1B까지 주소 지정 기능

가정 2. 프로세스별로 64KB 메모리 할당(가상 메모리)

가정 3. 메인 메모리 16KB(램 용량 16KB)

실제 메모리는 16KB가 전부지만, 프로세스 생성 시 64KB를 할당한다. 그러나, 16K번지 이상 메모리는 접근이 불가능하며, 16K-1번지까지만 접근이 가능하다. 이러한 문제를 해결하기 위해 다음 방법을 고안했다.

MMU(Memory Management Unit)의 존재가 보이는데, 이는 16KB 밖에 없는 메모리를 64KB가 존재하는 것처럼 CPU가 느끼도록 컨트롤하는 역할을 한다.

 

위 그림에서는 CPU와 MMU는 별개의 장치로 보이나, MMU는 CPU와 패키징되는 장치다. MMU의 작동 방식은 다음과 같다.

1. MMU에게 할당 내용을 전달한다.
2. MMU에서 메모리 블록을 골라 할당한다.

 

메모리는 필요한 만큼만 할당할 경우, 메모리 사용의 효율성이 증가한다. MMU는 데이터 블록만큼 크기를 전부 할당하게 되는데, 예를 들어서 메모리 블록의 크기가 4KB이며 12K-13K번지만 필요할 경우, 12K-16K를 전부 할당하게 된다. 이는 스페이셜 로컬리티의 특성을 살리기 위함이다.

 

데이터 블록을 하드웨어 입장에서는 페이지 프레임Page Frame이라고 하며, 소프트웨어 입장에서는 페이지Page라고 한다. 동일한 입장에서 두 단어를 설명하면, 페이지 프레임은 메인 메모리 블록을 의미하고, 페이지는 가상 메모리 블록을 의미하게 된다.

페이지 프레임과 페이지의 크기는 동일하다.

위 그림에서는 가상 메모리와 물리 메모리의 매핑Mapping을 보여준다.

페이지의 크기를 4KB로 정의하면, 64KB 메모리 공간에서 16개의 페이지를 얻을 수 있다. 페이지 테이블에서 키Key는 페이지 숫자를 뜻하고 값은 해당 페이지가 존재하는 페이지 프레임의 시작 번지다. 이러한 테이블 구성을 지닐 경우에 페이지 테이블을 참조하여 가상 주소를 실제 할당되어 있는 물리 주소로 변환할 수 있다.

 

▶ 예시

: CPU에서 10진수로 57354번지에 int형 데이터 350을 저장하라는 명령을 MMU로 전달 → MMU는 가상 주소 57354에 해당하는 물리 주소를 파악 -> 프레임 내에서 위치 결정 

03.C. 가상 주소Virtual Address 시스템 2

프로세스마다 가상 메모리를 사용하기에는 메모리 부족 문제가 존재한다. 이때, 하드디스크를 메인 메모리로 확장하는 스왑 파일Swap File이라는 개념을 사용한다. 

 

그러나 이 방법은 속도가 느리다는 단점이 있다. 그렇기 때문에 메모리의 속도 저하를 가져오는 방법을 왜 사용하는지에 의문을 가질 수 있으나, 이는 하드디스크와 메인 메모리를 동일 선상에 두었기 때문이다. 하드 디스크가 메인 메모리를 보조하는 격으로 생각해야 한다. 그러니까 하드디스크는 스왑 파일을 통해서 메인 메모리를 보조하는 것이지, 램과 동일하게 메인 메모리의 역할을 해내는 것이 아니다.

 

메인 메모리가 가득찬 상태에서 새로운 요청이 들어온다면, 메인 메모리는 하드디스크로 가지고 있는 데이터를 전달하고 새로운 데이터를 받아들인다. 그리고 하드디스크에 저장된 데이터가 필요해지면 다시 꺼내오는 식으로 하드디스크는 저장고의 역할을 한다.

 

실행중인 프로세스 A가 있고 대기 중인 프로세스 B가 있다. 이제, 프로세스 B를 실행시키려고 하는데 램에는 프로세스 A와 관련된 데이터가 있을 것이다. 이러한 경우 프로세스 A 데이터를 프로세스 A의 스왑 파일에 저장하고 프로세스 B의 실행에 필요한 데이터를 스왑 파일로부터 가져와 램에 추가한다. 이러한 과정을 반복하며, 둘 이상의 프로세스가 4G 바이트의 메모리를 할당 받아서 실행을 이어간다.

 

 

 

'독서 > 뇌를 자극하는 윈도우즈 시스템 프로그래밍' 카테고리의 다른 글

[스터디] 시스템 프로그래밍 - Chapter 15. 쓰레드 풀링Pooling  (1) 2023.11.24
[스터디] 시스템 프로그래밍 - Chapter 14. 쓰레드 동기화 기법 2  (1) 2023.11.08
[스터디] 시스템 프로그래밍 - Chapter 13. 쓰레드 동기화 기법 1  (1) 2023.11.08
[스터디] 시스템 프로그래밍 - Chapter 12. 쓰레드의 생성과 소멸  (2) 2023.11.01
[스터디] 시스템 프로그래밍 - Chapter 11. 쓰레드의 이해  (3) 2023.10.30
'독서/뇌를 자극하는 윈도우즈 시스템 프로그래밍' 카테고리의 다른 글
  • [스터디] 시스템 프로그래밍 - Chapter 15. 쓰레드 풀링Pooling
  • [스터디] 시스템 프로그래밍 - Chapter 14. 쓰레드 동기화 기법 2
  • [스터디] 시스템 프로그래밍 - Chapter 13. 쓰레드 동기화 기법 1
  • [스터디] 시스템 프로그래밍 - Chapter 12. 쓰레드의 생성과 소멸
태역
태역
  • 태역
    RYULAB
    태역
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 언어
        • C
        • C++
        • C#
      • 엔진, 프레임워크
        • Unity
        • Unreal
        • Electron
      • 공부 N
        • 디자인 패턴
        • 수학
        • CS N
        • Git
        • 알고리즘
        • 자료구조
      • 코테
        • 프로그래머스
        • 백준
      • 독서
        • Effective C#
        • CLR via C#
        • 뇌를 자극하는 윈도우즈 시스템 프로그래밍
        • 오브젝트
        • CSAPP
        • OSTEP
      • 프로젝트
        • Unity
      • 개발 일지
        • 퓨처리티
        • 골든타임
      • 활동
        • 게임잼 후기
        • 게임제작동아리 브릿지
        • 크래프톤 정글
        • 기타
      • 기타
  • 블로그 메뉴

    • 링크

    • 공지사항

      • 2024 04 17
    • 인기 글

    • 태그

      인프런 #인프런강의후기 #게임개발 #게임개발강의 #인강후기 #강의후기 #게임개발자 #인프런강의
      티스토리챌린지
      오블완
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    태역
    [스터디] 시스템 프로그래밍 - Chapter 16. 컴퓨터 구조의 4번째 이야기
    상단으로

    티스토리툴바