[cs 기초 갈고닦기] 메모리 요약 정리

khyojun·2023년 2월 16일
0

CS 기초 갈고 닦기

목록 보기
6/10
post-thumbnail

메모리

메모리는 기억을 위한 장치이다.
라고 이전 시간에 컴퓨터의 구성요소를 알아보면서 공부했었다. 오늘은 그 메모리를 집중적으로 알아보자.

메모리 계층

메모리 계층은 레지스터, 캐시, RAM(주 기억장치), 저장장치(HDD,SSD), 보조기억장치 순으로 구성된다.
메모리 계층 구조(Memory hierarchy) 란 메모리를 필요에 따라 여러 가지 종류로 나누어 둠을 의미한다. 이때 필요한 대부분의 경우 CPU가 메모리에 더 빨리 접근하기 위함이다.
메모리 계층 구조는 위에서 밑으로 갈 수록 비용이 싸지고, 저장할 수 있는 용량이 커진다는 특징을 가지고 있는데 하나씩 알아보자.

레지스터

레지스터는 CPU가 요청을 처리하는데 데 필요한 데이터를 임시로 저장하기 위한 기억장치이다.
이전에 CPU가 제어, ALU, 레지스터 로 구성이 되어있다고 했는데 그 중 레지스터인 것이다.

프로세서에 위치한 고속 메모리로, 프로세스가 바로 사용할 수 있도록 하는 데이터(소량의 데이터, 처리 중인 중간 결과 등)를 담은 영역이다.

그러한 CPU의 레지스터에도 여러 종류들이 있는데 확인해보자.

  • 프로그램 계수기(PC, Program Counter): 다음에 실행할 명령어(instruction)의 주소를 가지고 있는 레지스터
  • 누산기(AC, ACcumulator): 연산 결과 데이터를 일시적으로 저장하는 레지스터
  • 명령어 레지스터(IR, Instruction Register): 현재 수행 중인 명령어를 가지고 있는 레지스터
  • 상태 레지스터(SR, Status Register): 현재 CPU의 상태를 가지고 있는 레지스터
  • 메모리 주소 레지스터(MAR, Memory Address Register): 메모리로부터 읽어오거나 메모리에 쓰기 위한
    주소를 가지고 있는 레지스터
  • 메모리 버퍼 레지스터(MBR, Memory Buffer Register): 메모리로부터 읽어온 데이터 또는
    메모리에 써야할 데이터를 가지고 있는 레지스터
  • 입출력 주소 레지스터(I/O AR, I/O Address Register): 입출력 장치에 따른 입출력 모듈의 주소를
    가지고 있는 레지스터
  • 입출력 버퍼 레지스터(I/O BR, I/O Buffer Register): 입출력 모듈과 프로세서 간의 데이터 교환을 위해
    사용되는 레지스터
    이렇게 많은 종류의 내부 레지스터들이 CPU안에 존재를 한다. 그래서 이 안에 있는 작업들은 레지스터를 통해 하게 되는데 가장 빠르고, 저장공간이 가장 좁다는 것을 알고 가야겠다.

캐시

캐시는 데이터나 값을 미리 복사해 놓는 임시 장소로써, 시스템의 효율성을 위해 사용하는 것이다?

시스템의 효율성?

  • 캐시라는 임시 저장공간에 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우
  • 값을 다시 계산하는 시간을 절약하고 싶은 경우

캐시의 목적

속도가 빠른 장치(CPU)와 느린 장치(메모리) 사이에서 속도차에 따른 병목 현상을 완화하기 위한 용도이다.
그래서 캐싱이라는 단어도 존재한다.

캐싱 : 캐시라고 하는 좀 더 빠른 메모리 영역에서 데이터를 가져와서 접근하는 방식이다.
그래서 예시를 들어보면 여러 메모리 계층이 있지만 레지스터와 RAM사이의 속도 차이를 줄이고자 중간에 캐시라는 계층이 있는 것처럼 약간 중간에 존재하는 중재자같은 존재였다.

그리고 이러한 계층들을 캐싱 계층이라고도 부르기도 한다. (캐시 메모리, 보조기억장치 사이 있는 RAM도 캐싱계층이 된다.)

캐시의 종류

  • CPU 캐시 : 대용량의 메인 메모리 접근을 빠르게 하기 위해 CPU 칩 내부나 바로 옆에 탑재하는 작은 메모리이다.
    • 하드웨어를 통해 관리가 된다.
    • L1,L2,L3 캐시라는 종류의 캐시가 내부에 있다.(여기서 L은 level을 의미한다.)
  • L1 캐시 : 일반적으로 CPU 안에 내장되어 데이터 사용/참조에 가장 먼저 사용된다. 8~64kb정도 용량으로 가장 빠르게 접근, 여기서 못 찾으면 L2캐시 메모리로 넘어간다.
  • L2 캐시 : 용도는 L1과 비슷, 속도는 L1보다 느리며 RAM보다는 빠르다. 용량은 64kb~4MB정도이다.
  • L3 캐시 : 동일한 용도이긴 하지만 웬만한 프로세서는 L3를 달고있지 않는다. L2로도 충분히 커버할 수 있기 때문이다. 그래서 보통 듀얼 코어까지는 L3캐시는 없지만, CPU가 아닌 메인보드에 내장되는 경우가 많다.

실질적으로 L3캐시는 CPU 성능에 직접적인 영향을 끼치지는 않는다.

  • 디스크 캐시 : 하드디스크에 접근하는 시간을 개선하기 위해 RAM에 저장하는 기법이다. 하드디스크에 접근하는 것보다 RAM에 접근하는게 더 빠르기 때문

    • RAM과 보조기억장치 사이에 존재하는 캐시이다.
  • 기타 캐시

    • 위 하드웨어에 의해 다뤄지는 캐시와 달리 소프트웨어적으로 관리가 된다.
    • 페이지 캐시 : 운영 체제의 메인 메모리를 하드 디스크에 복사해 놓는 캐시(ex : 웹 브라우저의 웹 페이지 캐시)

캐시 설정 : 지역성에 따라

지역성이 뭐냐

지역성 : 캐시가 효율적으로 동작하려면, 캐시에 저장할 데이터가 지역성을 가져야 한다. 지역성이란 데이터 접근이 시간적, 혹은 공간적으로 가깝게 일어나는 것을 의미한다.
여기 지역성에는 2가지 종류가 있다.

  • 시간적 지역성: 특정 데이터가 한번 접근되었을 경우, 가까운 미래에 또 한번 데이터에 접근할 가능성이 높은 것을 시간적 지역성이라고 한다.
    메모리 상의 같은 주소에 여러 차례 읽기 쓰기를 수행할 경우 상대적으로 작은 크기의 캐시를 사용해도 효율성을 꾀할 수 있다.
  • 공간적 지역성 : 특정 데이터와 가까운 주소가 순서대로 접근되었을 경우를 공간적 지역성이라고 한다.
    접근된 기억장소와 인접한 기억장소에 접근 될 가능성이 높다는 것을 말한다.

캐시 히트와 캐시 미스

  • 캐시 히트 : CPU가 참조하고자 하는 메모리가 캐시에 존재하고 있을 경우 캐시 히트라고 한다.
  • 캐시 미스 : CPU가 참고하고자 하는 메모리가 캐시에 존재하지 않으면 캐시 미스라고 한다.

그런데 캐시 미스에는 여러가지 종류들이 존재한다고 한다.

  • compulsory miss(cold miss) : 해당 메모리 주소를 처음 불렀기 때문에 일어나는 미스이다. (프로그램을 새로 켰을때 일어나게 된다.)
  • conflict miss: 캐시 메모리에 a,b를 저장한다고 했을 때 a,b가 같은 캐시 메모리 주소에 할당되어서 일어나는 미스이다.
  • capacity miss : 캐시 메모리에 공간이 부족해서 나는 미스

캐시를 히트하게 되는 경우에는 해당하는 데이터를 제어장치를 거쳐서 가져오게 된다. 이 경우 위치도 가깝고 CPU 내부 버스를 기반으로 작동하기 때문에 빠르다.

그러나 캐시미스의 경우에는 메모리에서 가져와야 하는데 시스템 버스를 기반으로 작동하기 때문에 엄청 느리다.

캐시매핑

캐시매핑 : 캐시가 히트되기 위해 매핑하는 방법 , CPU의 레지스터와 RAM 간에 데이터를 주고받을 때 기반으로 주로 설명한다.
상대적으로 크기가 엄청 작은 레지스터와 주 메모리가 데이터를 주고 받기 위함인데 레지스터가 캐싱 계층으로써 역할을 잘 해주려면 이런 캐시 매핑을 잘해줘야 캐시 히트가 잘 될거다.

캐시매핑의 종류

  • 직접 매핑 : 메인 메모리에서와 동일한 배열을 가지도록 매핑을 한다. -> 메모리 1~100 캐시 1~10이라면 1 :1~10, 2:1~20 이런 식으로 찾는 단순한 방법이다.
    • 장점 : 탐색이 쉽기에 처리가 빠르다
    • 단점 : 충돌 발생이 많이 일어나고, 적중률이 낮다.
  • 연관 매핑 : 직접 매핑의 단점을 보완하기 위해 나온 매핑이다. 순서를 일치시키지 않고 관련 있는 캐시와 메모리를 매핑하는 것이다.
    • 장점 : 적중률이 높다.
    • 단점 : 모든 블록을 탐색해야 하기에 속도가 엄청 느리다.
  • 집합 연관 매핑 : 직접 매핑, 연관 매핑을 합쳐 놓은 것이다. 두 개의 장점만을 취하기 위하여 만든 방법이다. 순서를 일치시키지만 집합을 둬서 저장하며 블록화를 시킨다고 한다.

웹 브라우저의 캐시

소프트웨어적인 대표적인 캐시로 웹 브라우저들의 캐시들이 있다. 종류로는 쿠키, 로컬 스토리지, 세션 스토리지가 있다.

이러한 캐시들은 주로 사용자의 인증이나 커스텀한 정보들을 나중에 서버에 요청할 때 자신의 id나 중복 요청 방지를 막기 위하여 사용이 되곤 한다.

  • 쿠키 : 만료 기한이 있는 키-값 저장소, 4KB까지 데이터를 저장(보안이 잘 안됨)
  • 로컬 스토리지: 만료기한이 없는 키-값 저장소, 10MB까지 저장할 수 있고 웹 브라우저를 닫아도 계속 저장이 되어있다. HTML5에 추가된 저장소이다. 클라이언트에서만 수정 가능
  • 세션 스토리지 : 만료기한이 없는 키-값 저장소, 탭 단위로 세션 스토리지를 생성하고 탭을 닫으면 해당 데이터 삭제된다. 5MB까지 저장 되고 HTML5에서 추가되었다. 클라이언트에서만 수정 가능

로컬 세션 스토리지는 HTML5에서 추가된 스토리지라고 하는데 HTML5가 아닌 웹 브라우저에서는 사용할 수 없고 클라이언트에서만 수정이 가능하다고 한다. 이 둘의 가장 큰 차이점은 영구성이다.

로컬 스토리지는 데이터를 지우지 않는다면 계속 브라우저에 남아있지만, 세션은 탭을 닫으면 데이터가 자동으로 제거가 된다.

참고 : 데이터베이스에서도 캐싱 계층 : redis가 있다. 처음 요청할때는 쿼리를 날려야 하지만 두번째부터는 캐시에 저장되있는 친구를 가져와 사용할 수도 있다. 그러면 쿼리 요청을 줄일 수 있다.

주 기억장치(Main Memory)

주 기억장치이며 컴퓨터에서 수치, 명령, 자료 등을 기억하는 컴퓨터 하드웨어 장치이다.

크게 2 종류로 나뉜다.

  • RAM : 휘발성 기억 장치, 단기간 저장 구성 요소, 전원이 유지되는 동안 CPU의 연산 및 동작에 필요한 모든 내용 저장, 전원 종료시 기억된 내용 삭제
  • ROM : 고정 기억 장치, 비휘발성 메모리
    • 변경 가능성이 희박한 것을 저장
      • 소프트웨어 : 초기 부팅 관련 부분
      • 하드웨어 : 프린터 작동에 관여하는 펌웨어 명령 등

운영체제에서의 메모리 관리

컴퓨터라는 것도 한정적인 자원을 가진 부품이기에 여기에 있는 메모리라는 자원도 관리를 해줘야하는것도 운영체제의 책임이자 역할이다.
어떻게 역할을 수행하는지 알아보자.

가상 메모리

가상 메모리 : 메모리 관리 기법 중 하나, 실제로 이용 가능한 메모리 자원을 추상화하여 이를 사용하는 사용자들에게 매우 큰 메모리로 보이게 만드는 작업
책 p.148의 사진을 참고하여 설명하자면 가상적으로 주어진 주소를 가상 주소, 실제 메모리상에 있는 주소를 실제 주소라고 부르기로 했다. 이때 가상주소가 MMU라는 메모리관리장치에 의해서 실제 주소로 변환이 되어지기 때문에 사용자가 실제 주소를 의식할 필요 없이 프로그램을 구축할 수 있게 되었다.

그래서 진짜 가상 메모리가 뭔데?

라고 묻는다면

가상 메모리(Virtual Memory)는 이러한 물리적 메모리 크기의 한계를 극복하기 위해 나온 기술이다. 프로세스를 실행할 때 실행에 필요한 일부만 메모리에 로드하고 나머지는 디스크에 두는 것이다.
이를 통해서 프로세스 전체가 물리적 메모리에 있는 것 처럼 수행되는 효과를 얻어 수행하게 된다. 그래서 실제로는 메모리에 아주 작은 양의 주소 공간만 있어도 충분히 프로세스를 수행할 수 있는 것이다. 그에 다라 더 많은 프로그램을 동시에 실행할 수 있게 되는거다.

가상 메모리는 가상 주소와 실제 주소가 매핑되어 있고 프로세스의 주소 정보가 들어 있는 페이지 테이블로 관리되는데 이때 TLB를 사용한다.

  • 페이징: 어느 정도의 사이즈만큼 메모리에 올릴 지에 대한 결정을 내리기 위하여 나온 단위
  • 페이지 테이블: 가상 주소에 있는 페이지 번호와 해당 페이지의 첫 물리 주소 정보를 매핑한 표
  • TLB: 메모리와 CPU 사이에 있는 주소 변환을 위한 캐시, 페이지 테이블의 리스트를 보관하며 CPU가 페이지 테이블까지 가지 않도록 해 속도를 향상시켜주는 캐시 계층이다.
    솔직히 잘 이해가 되지 않는다.

가상 메모리라는 개념에 대해서 완전 처음부터 가보자. 애초에 프로세스를 실행하려고하는데 모든 전체에 해당하는 프로세스가 다 필요한게 아니라 일부만 필요하기 때문에 일부만 메모리에 로드하고 나머지는 디스크에 놔두는 거다.

그렇게 따지면 가상메모리는 무한대의 크기를 가질 수 있나? -> 이론적으로만 그렇다. 그러나 실제 가상 메모리의 최대 크기는 컴퓨터 시스템이 가진 물리 메모리의 최대 크기로 한정이 된다.

그리고 CPU의 비트에 따라 결정이 된다. 예를 들면 4gb의 메모리를 가진 곳에서 4gb만큼의 프로세스 10개를 실행시키면? 40gb가 필요한데 어떻게 해야될까?

이때 가상 메모리 시스템에서는 물리 메모리의 내용 중 일부를 하드디스크의 일부 공간, 즉 스왑 영역이라는 곳으로 옮기게 되는데!

스왑 영역 : 하드디스크에 존재하지만 메모리 관리자가 관리하는 영역으로 메모리의 일부, 가상 메모리의 구성 요소 중 하나.
그래서 만약 물리 메모리가 가득 차면 일부 프로세스를 스왑 영역(스왑 아웃)으로 보내고 몇 개의 프로세스가 작업을 마치면 스왑 영역에 있는 프로세스를 메모리로 가져온다.(스왑인)

이 말을 요약해보면 하드디스크의 일부를 스왑영역으로 사용하는데 가상 메모리 = 스왑 영역 + 물리 메모리를 합친거라고 봐도 된다.

위 스왑 영역을 활용한 것을 어찌보면 스와핑! 이라고 할 수 있다.

스와핑

하드디스크의 일부분을 마치 메모리처럼 불러와 쓰는 것을 스와핑이라고 한다.

페이지 폴트

페이지 폴트(page fault)란 프로세스의 주소 공간에는 존재하지만 지금 이 컴퓨터의 RAM(물리 메모리)에는 없는 데이터에 접근했을 때 발생! 그로 인한 스와핑이 일어나게 된다.
1. CPU는 물리 메모리를 확인하여 해당 페이지가 없으면 트랩(sw 인터럽트)를 발생시켜서 운영체제에 알린다.
2. 운영체제는 CPU의 동작을 잠시 멈춘다.
3. 운영체제는 페이지 테이블을 확인해 가상 메모리에 페이지가 존재하는지 확인하고, 없으면 프로세스를 중단하고 현재 물리 메모리에 비어 있는 프레임이 있는지 찾는다. 그 이후 물리 메모리에도 없으면 스와핑이 일어난다.
4. 비어 있는 프레임에 해당 페이지를 로드하고, 페이지 테이블을 최신화시킨다.
5. 중단된 CPU를 다시 시작한다.

이 과정에서 스왑인이 실행된거라고 볼 수 있다.

페이지: 가상 메모리를 사용하는 최소 크기 단위
프레임 : 실제 메모리를 사용하는 최소 크기 단위

스레싱

스레싱 : 메모리의 페이지 폴트율이 높은 것을 의미, 이는 컴퓨터의 심각한 성능 저하를 초래한다.
스레싱은 어찌보면 악순환이라고 불러도 될 거 같다. 왜냐하면 페이지 폴트율이 올라가게 되면 위 과정처럼 CPU가 멈추는 단계가 일어난다.

그런데 이렇게 CPU가 멈춰서 이용률이 낮아지면 운영체제는 "얘가 일을 안하네?"라고 인식해서 많은 프로세스를 또 메모리에 올린다. 그러면 계속 악순환이 돌게 되는 거다.

그래서 이를 해결하기 위해서는 메모리를 늘리거나, HDD를 SSD로 바꾸는 방법이 있다.

또 다른 방법으로는 운영체제에서 이를 해결할 수 있도록 작업 세트, PFF라는 방법들이 있다.

작업세트(working set)

프로세스가 일정 시간 동안 집중적으로 특정 주소 영역을 참조하는 경향이 있는데 이를 지역성 집합이라고 합니. 워킹셋 알고리즘은 지역성 집합이 메모리에 동시에 올라갈 수 있도록 보장하는 메모리 관리 알고리즘입니다.
워킹셋은 한꺼번에 메모리에 올라가야 하는 페이지들의 집합인데 한꺼번에 올라갈 수 있는 메모리 공간이 있을 때만 동작을 하게 된다. 그렇지 않은 경우에는 기존 메모리의 페이지를 디스크로 스왑 아웃 시켜 공간을 확보한다.

이런 방법으로 하면 미리 메모리에 로드를 하기에 탐색에 드는 비용을 줄이고 스와핑 또한 줄일 수 있다고 한다.

PFF(Page Fault Frequency)

페이지 폴트 빈도를 조절하는 방법으로 상한선과 하한선을 만들어서 상한선에 도달하면 프레임을 늘리고 하한선에 도달하면 프레임을 줄이는 것이다.

메모리 할당

메모리에 프로그램을 할당할 때는 시작 메모리 위치, 메모리의 할당 크기를 기반으로 할당을 하게 된다. 그때 연속 할당, 불연속 할당으로 나뉘게 된다.

연속 할당

연속된 하나의 큰 메모리에서 프로세스에 메모리를 할당시켜주는 기법인데 2가지가 있다.

  • 고정크기 메모리할당: 메모리를 고정된 크기로 나누고 프로세스를 할당시킨다.
    • 미리 정해진 크기로 나누기 때문에 융통성이 없다.
    • 내부 단편화가 일어나게 된다.
  • 가변크기 메모리할당: 프로세스마다 요구되는 메모리 크기에 맞춰서 메모리를 할당시킨다.
    • 내부 단편화는 발생하지 않고 외부 단편화가 발생할 수 있다.
    • 가변크기 할당 방식에는 최초적합, 최적적합, 최악적합에 따라 할당을 하게 된다.
      • 최조 적합(first fit): 위쪽이나 아래쪽부터 시작해서 비어있는 곳을 찾으면 바로 할당한다.
      • 최적 적합(best fit): 프로세스의 크기 이상인 공간 중 가장 작은 공간부터 할당한다.
      • 최악 적합(worst fit): 프로세스의 크기와 가장 많이 차이가 나는 비어있는 곳에 할당한다.
  • 내부 단편화 : 메모리를 나눈 크기보다 프로그램이 작아서 들어가지 못하는 공간이 많이 발생하는 현상
  • 외부 단편화 : 메모리를 나눈 크기보다 프로그램이 커서 들어가지 못하는 공간이 많이 발생하는 현상
  • 홀(hole) : 할당할 수 잇는 비어 있는 메모리 공간

불연속 할당

하나의 프로세스가 물리적 메모리의 여러 위치에 분산되어 올라갈 수 있는 메모리 할당 기법이다. 이 기법은 현대 운영체제가 쓰는 방법으로 페이징 기법, 세그멘테이션, 페이지드 세그멘테이션이 있다.

  • 페이징 기법 : 프로세스의 주소 공간을 동일한 크기의 페이지 단위로 나누어 물리적 메모리의 서로 다른 위치에 페이지들을 저장하는 방식
    • 홀의 크기가 균일하지 않은 문제가 없어지지만 주소 변환이 복잡해질 수 있다.(분산 시켜놨기 때문에)

출처

profile
코드를 씹고 뜯고 맛보고 즐기는 것을 지향하는 개발자가 되고 싶습니다

0개의 댓글