6주차 - Chapter 14~15

 
Feb 8, 2023

Contents


Chapter 14 가상 메모리

들어가기

가상 메모리

💡
오랫동안 사용되지 않은 프로세스 또는 프로세스의 일부 영역을 보조기억장치로 옮겨서 메모리 공간을 확보한다. 그렇게 확보한 메모리 공간에 다른 프로세스를 추가로 적재하여 한번에 더 많은 프로세스를 실행할 수 있게 하는 방법
  • 프로그램이 CPU에 의해 실행되려면, 기본적으로 보조기억장치에 프로그램이 저장되어 있는 상태에서 프로그램을 메모리에 적재해야 한다. 프로그램이 메모리에 적재되면, 이에 해당하는 프로세스가 생성된다. 운영체제는 프로세스 단위로 프로그램의 실행을 제어한다. 자원 할당 및 회수와 같은 스케줄링과 같은 방법으로 말이다.
  • 실행할 수 있는 프로그램은 보조기억장치의 큰 용량만큼 많지만, 한 번에 실행할 수 있는 프로그램의 수는 메모리의 용량만큼 제한적이다. 따라서, 한정된 용량의 메모리 용량으로 가능한 한 많은 프로그램을 실행하는 것이 효과적이라 할 수 있다.
  • 메모리에 적재되어 있는 프로그램에는 실질적으로 실행 중인 프로그램이 있는 한편, 입출력 작업으로 인해 CPU가 실행중이지 않은 프로그램이 있고, 혹은 메모리에 적재된 프로그램 중 일부만 실제로 접근되어 쓰이고 대부분은 접근되지 않은 채로 메모리에 적재되어 있는 경우도 있다.
  • 따라서, 메모리에 실질적으로 실행되고 있는 프로그램들을 더 많이 넣고, 한정된 메모리 공간을 더 효과적으로 활용하기 위해 잠시 쓰이지 않는 프로세스의 일부분을 보조기억장치에 놓고, 쓰일 때에 다시 메모리에 적재되는 방식을 사용한다. 이를 스와핑 (swapping)이라 한다. 스와핑은 가상 메모리의 핵심 기능이다.
    • 프로세스의 일부분이 저장되는 영역은 보조기억장치 내부에서의 별도의 공간에 위치하는데, 이 영역을 스왑 공간 (swap space)라 한다.
    • 메모리에 있는 프로세스의 일부분을 보조기억장치에 놓는 것을 스왑아웃 (swap-out)이라 한다.
    • 그 반대로, 보조기억장치에 있던 프로세스의 일부분을 다시 메모리에 적재하는 것을 스왑인 (swap-in)이라 한다.
  • 스와핑을 활용하면 메모리 용량보다 실행하고자 하는 프로세스들의 용량의 총합이 더 큰 경우에도 실행할 수 있다.
    • 프로세스들의 총량이 메모리의 총량을 넘어서는 경우, 모든 프로세스를 메모리에 적재하지 않고 일부는 보조기억장치에 스왑아웃한다.
    • 일정한 주기로 스왑아웃된 프로세스의 크기 안쪽으로 들어가는 프로세스를 스왑아웃하고, 다시 스왑아웃되었던 프로세스를 스왑인하여 실행되지 않았던 프로세스를 실행한다.
    • 이렇게 하면, 한정된 메모리 공간으로 더 많은 프로세스들을 실행할 수 있다.
       

메모리 할당

  • 메모리 내에 빈 공간이 여러 개일 때, 어디에 프로세스를 적재하는 게 좋을까?
  • 적재하는 방법에는 크게 두 종류의 방법이 있는데, 하나는 연속 할당, 다른 하나는 불연속 할당이다.
    • 여기에서는 연속 할당과, 불연속 할당 중 페이징에 대해서만 다룬다.
 

연속 메모리 할당

💡
프로세스를 메모리에 할당할 때, 메모리에서 비어있는 공간 순서대로 할당하는 방식
  • 연속 메모리 할당에서, 프로세스를 메모리에 적재하는 세 가지 기준점이 있다. 상황에 맞게 적용할 수 있다.
      1. 최초 적합 (First fit) : 적재하려는 프로세스가 적재될 수 있는 크기 이상의 빈 공간을 처음으로 발견했을 때, 여기에 적재하는 것을 의미한다.
      1. 최적 적합 (Best fit) : 빈 공간을 모두 탐색하고, 적재하려는 프로세스가 적재될 수 있는 빈 공간들 중 가장 작은 공간에 적재하는 것을 의미한다.
      1. 최악 적합 (Worst fit) : 빈 공간을 모두 탐색하고, 적재하려는 프로세스가 적재될 수 있는 빈 공간들 중 가장 큰 공간에 적재하는 것을 의미한다.
 
  • 외부 단편화 (External Fragmentation)
    • 메모리 낭비 현상으로, 빈 공간에 프로세스가 할당되고도 남는 빈 공간외부 단편화라고 한다.
    • 외부 단편화로 인해 생긴 빈 공간들은 프로세스가 할당되기에는 너무 작아 활용하기 어렵다.
 
  • 압축 (Compaction)
    • 외부 단편화가 발생한 빈 공간들을 한데 모아, 외부 단편화도 해결하고 메모리 공간도 확보할 수 있게 하는 방법이다.
    • 단점
      • 빈 공간들을 하나로 모으는 동안 시스템은 하던 일을 멈춰야 하고, 메모리에 있는 내용을 옮기는 과정은 많은 오버헤드를 야기한다.
      • 어떤 프로세스를 어떻게 움직여야 오버헤드를 최소화하며 압축할 수 있는지에 대한 방법을 찾는 것이 어렵다.
    • 연속 메모리 할당에서의 외부 단편화 문제를 해결하기 위한 방법으로 페이징이 널리 쓰이고 있다.
 

페이징

💡
메모리의 논리주소공간, 물리주소공간 모두 일정한 크기의 페이지, 프레임으로 각각 분할한다. 프로세스의 크기만큼의 페이지, 프레임 개수만큼 프로세스에 할당한다.
  • 특징
    • 페이징은 스왑 인/아웃 시, 프로세스 단위로 스왑하는 것이 아닌 페이지 단위로 스왑한다.
    • 논리주소공간과 물리주소공간은 일정한 크기로 그 공간이 분할되는데, 논리주소공간을 일정한 크기로 분할한 것을 페이지, 물리주소공간을 일정한 크기로 분할한 것을 프레임이라고 한다. 두 주소공간은 같은 크기로 분할되어야 한다.

프로세스 할당과 페이지 테이블

  • 페이징에서 프로세스는 물리주소공간의 빈자리 (프레임)에 할당되기 때문에 프레임의 배치가 불연속적일 수 있다.
    • CPU는 물리주소공간을 바탕으로 프로세스를 실행하는데, 이때 주소공간을 순차적으로 접근하면서 실행해야 하므로 프레임의 배치가 불연속적이라면 제대로 실행할 수 없다.
    • 따라서, 물리주소공간의 비어있는 프레임에 프로세스를 할당하면서, CPU는 기존 방식대로 주소공간을 순차적으로 접근하며 프로세스를 실행하려면 추가적인 방법이 필요하다.
 
  • 페이지 테이블
    • 💡
      논리주소공간에서의 페이지 순번과 이에 대응하는 물리주소공간에서의 프레임 순번을 매핑한 것들을 열거한 테이블
    • 앞서 언급한 물리주소공간에서의 프레임은 실제 CPU가 접근하여 실행해야 하는 부분이다. 하지만, 그 자체가 불연속적으로 할당되어 있어 CPU가 순차적으로 접근하며 실행하기에는 어렵다.
    • 그렇다면, 논리주소공간은 어떨까?
      • 논리주소공간은 해당 프로세스만이 사용하는 주소공간이다. 따라서, 여러 프로세스들이 할당하는 물리주소공간과 달리 연속적으로 페이지를 할당한다 해도 문제되지 않는다.
      • 따라서, CPU는 논리주소공간에서의 페이지를 물리주소공간에서의 프레임 대신 순차적으로 참조하고, 논리주소공간과 물리주소공간 사이에 별도로 위치한 페이지 테이블에서 페이지 순번과 짝지어진 프레임 순번을 찾는다.
      • CPU가 페이지 테이블에서 찾은 프레임 순번으로 물리주소공간에서의 프레임에 접근하여 필요한 작업을 수행한다. (읽기, 쓰기 등등)
 
  • 내부 단편화 (Internal Fragmentation)
    • 프로세스의 크기만큼 모든 페이지에 나누어 할당할 때, 어떤 페이지는 그 크기를 다 채우지 못해 페이지 내부에 공간이 남아돌 수 있다. 이렇게 재활용되지 못하는 영역을 내부 단편화라고 한다.
 
  • 페이지 테이블 베이스 레지스터 (PTBR)
    • 💡
      프로세스마다 독립적으로 페이지 테이블을 가지고 있고, 각 프로세스의 페이지 테이블들은 메모리에 적재되어 있다.
    • 현재 실행중인 프로세스의 페이지 테이블이 위치한 메모리 주소를 저장하는 레지스터를 페이지 테이블 베이스 레지스터라고 한다.
      • 예를 들어, 프로세스 A가 현재 실행중이라면 페이지 테이블 베이스 레지스터는 프로세스 A의 페이지 테이블이 위치한 메모리 주소를 저장하고 있다는 것이다.
 
  • TLB (Translation Lookaside Buffer)
    • 페이지 테이블은 메모리 내부에 위치해 있는데, 이것 자체가 오버헤드를 야기한다.
      • CPU가 페이지 테이블을 활용하여 프레임에 접근하는 과정은 크게 두 가지다. 이때 메모리에 두 번 접근하게 되면 당연하게도, CPU가 프레임에 접근함에 있어 필요로 하는 메모리 접근 시간이 두 배로 늘어나기 때문이다.
          1. CPU가 찾고자 하는 페이지 번호를 바탕으로 메모리의 페이지 테이블에 접근하여, 페이지 번호와 짝지어진 프레임 번호를 알아낸다.
          1. CPU는 메모리의 물리주소공간에 접근하여 프레임 번호를 찾고, 여기에 해당하는 프레임에 접근하여 작업을 수행한다.
       
    • 메모리 접근 횟수를 1회로 줄이고자 페이지 테이블에 대한 캐시 메모리가 도입되었는데, 이를 TLB라고 한다. TLB는 CPU 주변에 위치해 있으며, 페이지 테이블 내용의 일부분을 저장하고 있다.
      • CPU는 페이지 테이블에 접근하기에 앞서, 참조하고자 하는 페이지 번호가 TLB에 있는지 확인한다.
        • 이때 TLB에 해당 페이지 번호가 있다면 메모리의 페이지 테이블에 접근하는 과정을 생략하고, 이에 짝지어진 프레임 번호를 가지고 곧바로 물리주소공간의 프레임에 접근한다. (TLB Hit)
        • 만약 TLB에 해당 페이지 번호가 없다면, 원래 과정대로 메모리의 페이지 테이블에 접근하여 페이지 번호와 짝지어진 프레임 번호를 찾고, 이어서 물리주소공간의 프레임에 접근한다. (TLB Miss)
 
  • 페이지 테이블에서의 주소 변환
    • 하나의 페이지 또는 프레임은 여러 주소를 포함하고 있다.
      • ex) 페이지, 프레임 모두 순번당 4번지를 가짐 → 1번 페이지 : 0~3번지 / 2번 페이지 : 4~7번지 / …
       
    • 특정 주소에 접근하려면, 두 가지 정보가 필요하다.
        1. 어떤 페이지 또는 프레임에 접근하고자 하는지 → 페이지 번호
        1. 접근하려는 주소가 그 페이지 혹은 프레임으로부터 얼마나 떨어져 있는지 → offset
       
    • 페이징 시스템에서는 모든 논리 주소가 기본적으로 페이지 번호와 offset으로 이루어져 있다.
      • ex) 페이징 시스템에서의 32비트 주소 중 N비트가 페이지 번호라면, (32-N)비트는 offset
      •  
    • page number와 offset으로 물리주소공간의 원하는 번지 찾기
        1. CPU에서 주어진 페이지 번호를 통해 페이지 테이블에서 페이지 번호를 찾는다.
        1. 프레임 번호와 offset를 가지고 물리주소공간에서 프레임 번호대로 프레임을 찾고, 해당 프레임 번호의 시작 번지에 offset을 더한다.
        이렇게 구한 번지가 원하는 번지가 된다.
 
  • 페이지 테이블 엔트리
    • 엔트리 : 페이지 테이블의 각 row를 의미한다.
    • 페이지 테이블의 column들
      • 지금까지는 column들 중에서 페이지 번호, 프레임 번호만 다뤘지만, 사실 그 외에 더 많은 column들이 있다. 그 column 중에서는 중요한 정보를 나타내는 것들도 있다.
      • 유효 비트 (Valid bit) : 현재 페이지가 접근 가능한지 나타내는 비트. 보통은 페이지가 스왑 영역인지 아닌지를 나타내기 위해 쓰인다. 페이지가 메모리에 적재되어 있는 상태면 1, 그렇지 않다면 0이다.
      • 보호 비트 (Protection bit) : 페이지 보호 기능을 위한 비트. 0이면 읽기만 가능한 페이지를 나타내고, 1이면 읽기, 쓰기 모두 가능한 페이지를 나타낸다.
        • 읽기 (r), 쓰기 (w), 실행 (x)로 보호 비트를 세분화하여 나타낼 수 있다.
      • 참조 비트 (Reference bit) : CPU가 이 페이지에 접근한 적이 있는지 여부를 나타내는 비트. 메모리에 적재된 이후 참조된 적이 있다면 1, 없다면 0이다.
      • 수정 비트 (Modified bit, Dirty bit) : 해당 페이지에 데이터를 쓴 적이 있는지 없는지 수정 여부를 나타내는 비트. 수정된 적이 있다면 1, 없다면 0이다.
        • CPU가 메모리에 값을 쓰는 상황일 때, 메모리에는 값이 변경되었지만 보조기억장치에 저장된 페이지에서는 여전히 업데이트되지 않은 값이 저장되어 있어 변경사항이 충돌하기 때문이다.
          • → 따라서, 메모리에서 데이터가 변경되었음을 페이지에 기록함으로써, 보조기억장치에 있는 페이지가 스왑-인되어 CPU에 의해 실행될 때 변경된 값에 따라 처리될 것이다.
 
  • 페이징의 이점 - 쓰기 시 복사
    • 프로세스 간 페이지 공유하는 사례
      • 부모, 자식 프로세스 모두 논리 주소 공간의 페이지는 각자 갖지만, 물리주소공간에서의 프레임은 두 프로세스가 모두 동일하게 페이지 테이블 상에서 매핑되어 있다.
        • → 똑같은 내용의 영역을 그대로 물리 공간에 복제하지 않고, 두 프로세스의 페이지가 같은 프레임을 참조하게 함으로써, 메모리 공간을 절약할 수 있는 장점이 있다.
           
  • 계층적 페이징 (Hierarchical paging)
    • 다단계 페이지 테이블 (Multilevel page table)이라고도 한다.
    • 프로세스를 이루는 페이지 테이블 엔트리의 일부만 페이지에 유지하고, 나머지는 필요할 때까지 보조기억장치에 저장해두는 기법
    • 페이지 테이블 속에 있는 페이지 테이블을 관리하는 구조이므로, CPU가 사용하는 논리 주소가 다르다.
      • 계층적 페이징 미적용
        • offset - 페이지 번호
      • 계층적 페이징 적용
        • 외부 페이지 번호 - 내부 페이지 번호 - offset
       
    • 계층적 페이징에서의 주소 변환 과정
        1. 바깥 페이지 번호를 통해, 페이지 테이블의 페이지를 찾는다.
        1. 페이지 테이블의 페이지를 통해, 프레임 번호를 찾고, 여기에 offset을 더하여 최종적으로 접근할 물리 주소를 구한다.
        💡
        계층적 페이지에서의 페이지 테이블들의 계층은 2단계 그 이상으로도 가능하다. 하지만, 계층이 늘어날수록 페이지 폴트가 발생했을 때 메모리 참조 횟수가 증가하므로 무작정 좋지는 않다. - 페이지 계층이 올라가면, 메모리 관리 효율성이 증가한다. - 페이지 계층이 올라가면, 페이지 폴트 시 발생하는 오버헤드가 증가한다.
 
 

페이지 교체와 프레임 할당

요구 페이징 (Demand paging)

💡
처음부터 프로세스의 모든 페이지를 메모리에 적재하는 것 대신에, 처음부터 쓰일 페이지들만 메모리에 적재하는 기법
  • 요구 페이징의 기본적인 양상
      1. CPU가 특정 페이지에 접근하는 명령어를 실행한다.
      1. 해당 페이지가 현재 메모리에 있을 경우 (유효 비트가 1인 경우), CPU는 페이지가 적재된 프레임에 접근한다.
      1. 해당 페이지가 현재 메모리에 없을 경우 (유효 비트가 0인 경우), 페이지 폴트가 발생한다.
      1. 페이지 폴트가 발생하면, 실행에 필요한 페이지가 현재 메모리에 적재되어 있지 않다는 뜻이므로 보조기억장치에서 해당 페이지를 가져와 메모리에 적재한다. (스왑-인)
      1. 다시 1번부터 실행한다.
 
  • 그 외에, 프로세스를 처음 실행할 때에 페이지를 아무것도 메모리에 적재하지 않고 실행할 수도 있다.
    • 이 경우에는 메모리에 실행하고자 하는 페이지가 하나도 없으므로 처음에 무조건 페이지 폴트가 발생한다. 그렇게 페이지가 충분히 메모리에 적재될 때까지 페이지 폴트가 자주 발생하는데, 충분히 메모리에 적재될 때부터는 페이지 폴트가 거의 발생하지 않는다. 이를 순수 요구 페이징 (Pure Demand Paging)이라고 한다.
 
  • 메모리 공간은 유한하다. 따라서, 페이지를 메모리에 계속 적재하다 보면 메모리 공간이 부족해지게 된다. 그럴 경우 기존에 적재되어 있던 페이지들 중 일부를 다시 보조기억장치로 내보내야 하는데 (스왑-아웃), 어떤 기준에 따라 페이지를 내보내야 하는지 고민할 필요가 있다.
    • 이러한 기준을 제시하는 알고리즘을 페이지 교체 알고리즘 (Page Replacement Algorithm)이라고 한다.
 

페이지 교체 알고리즘 (Page replacement algorithm)

  • 페이지 교체 알고리즘의 성능 평가 기준은 페이지 폴트의 발생 빈도로, 페이지 폴트가 적게 발생하는 알고리즘일수록 성능이 좋은 알고리즘이라고 할 수 있다.
    • 반대로 페이지 폴트가 많이 일어나면, CPU는 메모리와 보조기억장치 간 스왑 작업을 하는 데 적지 않은 시간을 소비하게 되기 때문에 프로세스 실행에 더 적은 시간을 소비하게 된다. 따라서 CPU 활용률이 떨어지게 되고 이는 곧 성능 하락으로 이어진다.
 
  • 페이지 참조열 (Page Reference String)
    • CPU가 참조하는 페이지들 중에서 연속된 페이지를 생략한 페이지열을 의미한다.
      • ex) 페이지 순번으로 나열했을 경우
        • 2, 2, 2, 3, 4, 5, 5, 2, 2, 2 → (참조열) 2, 3, 4, 5, 2
          이런 식으로 나타낼 수 있다.
    • 연속된 페이지에서는 페이지 폴트가 발생하지 않기 때문에, 연속된 페이지를 페이지 하나로 나타낸다. (연속된 페이지 자체를 고려하지 않는다)
 
  • 페이지 교체 알고리즘들
    • 💡
      메모리 공간이 부족한 상황에서 페이지 폴트가 발생했을 때, 어떤 기준으로 기존에 적재되어 있던 페이지를 스왑아웃할 것인지를 결정하는 것이 핵심이다.
      1. FIFO 페이지 교체 알고리즘 (First-In First-Out)
        1. 현재 메모리에 적재되어 있는 페이지들 중 가장 먼저 적재된 페이지를 스왑아웃한다.
          • 장점 : 단순하여 구현이 간단함
          • 단점 : 프로그램 실행 내내 사용되는 페이지가 있다면, 가장 먼저 적재되었다고 스왑아웃되면 페이지 폴트 발생 빈도가 크게 높아질 위험이 있어 항상 유리한 알고리즘이라고 보기 어려움
          • 보완책 : 2차 기회 페이지 교체 알고리즘 (Second chance)
            • FIFO에서 자주 참조되는 페이지가 스왑아웃되는 것을 피하기 위해 고안된 알고리즘이다.
            • 기본적으로는 FIFO와 동일하게 메모리에 적재된 페이지들 중 가장 오래된 페이지를 찾는다.
            • 선별된 페이지의 참조 비트가 1일 경우, 최근에 참조한 페이지를 뜻하므로 나중에 스왑아웃해야 하는 페이지임을 확인할 수 있다. 따라서 해당 페이지의 참조 비트를 0으로 만들고 최근에 적재된 페이지로 다시 취급한다.
            • 반대로, 선별된 페이지의 참조 비트가 0일 경우, 가장 오래된 페이지면서 참조된 적 없는 페이지임을 확인할 수 있다. 따라서 해당 페이지를 스왑아웃하고 새로운 페이지를 스왑인한다.
           
      1. 최적 페이지 교체 알고리즘 (Optimal)
        1. CPU에 의해 얼마나 자주 참조되는 페이지인지를 스왑인 시점에서 미리 예측하고, 그 예측에 따라 이후 페이지 교체해야 할 상황에서 어떤 페이지를 교체할지 결정한다.
          💡
          이론상의 페이지 교체 알고리즘으로, 페이지 교체 알고리즘의 성능 비교를 위한 기준으로 쓰이고 있다. 최적 페이지 교체 알고리즘의 페이지 폴트 발생 빈도가 가장 낮기 때문에, 페이지 교체 알고리즘의 성능 평가에서 페이지 폴트 발생 빈도를 평가할 때 하한선으로 최적 페이지 교체 알고리즘의 페이지 폴트 발생 빈도가 활용된다.
          • 스왑아웃을 해야 할 페이지는 앞으로 사용 빈도가 가장 낮은 페이지여야 한다. 따라서, 앞으로의 사용 빈도가 가장 낮은 페이지를 교체하는 알고리즘을 페이지 교체 알고리즘으로 채택하는 것이 가장 합리적이다. 따라서 최적 페이지 교체 알고리즘이란 이름이 붙었다.
          • 한계 : 페이지를 스왑인할 때마다 얼마나 참조되는지에 대한 빈도를 정확히 예측하는 것은 매우 힘들다. 따라서 실제로 이를 구현하지 않는 대신 다른 페이지 교체 알고리즘의 성능 비교에서만 쓰인다.
           
      1. LRU 페이지 교체 알고리즘 (Least Recently Used)
        1. 최적 페이지 교체 알고리즘과 비슷하지만, 페이지 참조에 대한 빈도를 미리 예측하는 대신 현재 기준으로 얼마나 자주 참조되었는지에 대한 비교를 통해 교체할 페이지를 결정한다는 차이가 있다.

선택 미션 : 각 페이지 교체 알고리즘에서 페이지 폴트 발생 횟수 계산하기

notion image

스래싱과 프레임 할당

  • 스래싱 (Thrashing)
    • 페이지 폴트가 발생하는 근본적인 이유는 “적재 가능한 프레임 개수의 부족”이다.
    • 프로세스가 실제 실행되는 시간보다, 페이징에 더 많은 시간을 소요하여 성능이 저하되는 문제를 스래싱이라고 한다.
 
  • 멀티프로그래밍의 정도 (Degree of multiprogramming)
    • 메모리에서 동시에 실행되는 프로세스의 수
    • 멀티프로그래밍의 정도가 높다면 현재 메모리에는 많은 프로세스가 동시에 실행하고 있음을 뜻하고, 낮다면 현재 메모리에는 적은 프로세스가 동시에 실행되고 있음을 뜻한다.
    • 동시에 실행되는 프로세스가 증가할수록, CPU 활용률이 높아지는 것은 아니다. 메모리가 수용할 수 있는 페이지의 수가 한정적이기 때문에, 동시에 실행해야 할 프로세스의 수가 증가할수록 프로세스마다 적재될 수 있는 페이지의 수는 감소하게 된다.
    • 따라서, 동시에 실행되는 프로세스가 많아지게 되면 프로세스마다 실행에 필요한 페이지를 찾지 못할 확률이 높아지게 되어 페이지 폴트의 빈도는 증가하게 되고, 그로 인해 CPU가 실질적으로 프로세스의 실행을 처리하는 시간보다 페이지 폴트를 처리하기 위한 스왑인, 스왑아웃을 처리하는 시간이 더 길어지게 된다. 다시 말해서, 동시에 실행되는 프로세스가 어느 정도 그 이상으로 증가한다면 CPU 활용률은 더 떨어지게 된다는 것이다.
 
  • 프레임 할당 방식
    • 멀티프로그래밍의 정도에서 알아보았듯이, 프로세스마다 페이지를 얼마만큼 적재하게 할지에 따라 CPU 활용률을 개선할 수 있지 않을까? 얼마만큼 적재할지에 대한 방법으로, 여기에서는 균등 할당과 비례 할당에 대해 알아보겠다.
    • 균등 할당 (Equal allocation)
      • 프로세스마다 똑같은 양의 페이지 개수를 할당하는 방법
      • 한계
        • 실행되는 프로세스의 크기는 저마다 다르기에, 모든 프로세스에 동일한 개수의 페이지를 할당하는 것은 비효율적이다.
    • 비례 할당 (Proportional allocation)
      • 프로세스의 크기에 따라 페이지의 양을 조절하여 할당하는 방법
        • 큰 용량의 프로세스에는 페이지를 많게, 작은 용량의 프로세스에는 페이지를 적게 할당한다.
      • 한계
        • 프로세스의 크기가 크거나 작더라도, 그 크기와 다르게 실제 실행할 때에는 더 많거나 더 적은 페이지를 필요로 한다.
        • 따라서, 프로세스 실행 전에 할당할 페이지 개수를 정하기보다는 실행하는 시점에 페이지 개수를 정하는 것이 합리적이다. 실질적으로 프로세스의 실행에 필요한 페이지 개수를 정하는 것이 가장 정확하기 때문이다.
 
  • 프로세스를 실행하는 과정에서 배분할 프레임을 결정하는 방식
    • 작업 집합 모델 (Working set model)
      • 프로세스가 일정 기간동안 참조한 페이지 집합 (작업 집합)을 기억하여 빈번한 페이지 교체를 방지한다. (자주 참조한 페이지들을 기억한다)
    • 페이지 폴트 빈도 (PFF; Page-Fault Frequency)
      • 페이지 폴트가 자주 일어나면 프로세스에 할당된 페이지 개수가 부족함을 의미한다 → 더 많은 페이지 개수 할당
      • 페이지 폴트가 드물게 일어나면 프로세스에 할당된 페이지 개수가 많음을 의미한다 → 페이지 개수 일부 회수하여 다른 프로세스에 할당
 

Chapter 15 파일 시스템

파일과 디렉토리

  • 파일 : 보조기억장치 상에서 의미 있고 관련 있는 정보를 모은 논리적 단위
    • 파일 관련 부가 정보로는 속성과 메타데이터 등이 있다.
    • 파일 속성에는 파일 유형, 형식, 위치, 크기와 같은 정보가 있다.
    • 파일 속성 중 파일 유형은 운영체제가 인식하는 파일 종류를 나타낸다. 운영체제에 파일 유형을 알리기 위한 수단이 바로 파일명 뒤에 붙는 확장자다.
    • 파일을 다루는 모든 작업은 운영체제에 의해 이루어진다. 따라서 사용자 레벨에서 파일을 다루려면 파일 처리를 수행하는 기능을 하는 시스템 콜을 호출하여 운영체제가 이를 처리할 수 있도록 해야 한다.
      • 파일 연산에는 생성, 삭제, 열기, 닫기, 읽기, 쓰기가 있다.
 
  • 디렉토리 : 파일들을 일목요연하게 관리하기 위한 자료구조
    • 과거에는 모든 파일이 하나의 디렉토리 아래에 위치해 있었는데, 이러한 디렉토리 구조를 1단계 디렉토리라고 한다. (Single level directory)
    • 효율적인 파일 관리를 위해 여러 계층으로 분화되었는데, 이를 트리 구조 디렉토리라고 한다. (Tree-structured directory)
      • 루트 디렉토리 : 디렉토리의 최상위 디렉토리를 의미한다.
    • 디렉토리 관련 작업도 파일과 마찬가지로 운영체제에 의해 이루어진다. 따라서 그에 따른 시스템 콜 또한 제공된다.
      • 디렉토리 연산에는 생성, 삭제, 열기, 닫기, 읽기가 있다.
 
  • 절대 경로와 상대 경로
    • 절대 경로 : 루트 디렉토리로부터 시작하는 경로 ex) /Users/myid/Desktop/a.txt
    • 상대 경로 : 현재 디렉토리로부터 시작하는 경로 ex) ./mydirectory/a.tar
 
  • 디렉토리 엔트리
    • 💡
      디렉토리 또한 파일의 일종이지만, 디렉토리에는 추가적인 정보가 포함되어 있다.
    • 파일과의 차이점?
      • 파일이 내부에 해당 파일과 관련된 정보를 담고 있다면, 디렉토리는 그 내부에 해당 디렉토리에 담겨 있는 대상과 관련된 정보를 담고 있다.
      • 디렉토리에 있는 대상과 관련된 정보는 보통 테이블 형태로 구성된다.
      • 디렉토리는 보조기억장치에 테이블 형태의 정보로 저장된다.
    • 디렉토리 엔트리는 테이블 형태의 정보에 기록된 row로, 어떤 파일 시스템이던 디렉토리에 포함된 대상의 이름과 그 대상이 보조기억장치 내에 저장된 위치를 유추할 수 있는 정보를 포함하고 있다.
 

파티셔닝과 포매팅

  • 파일 시스템 : 파일과 디렉토리를 보조기억장치에 일목요연하게 저장하고 접근할 수 있게 하는 운영체제의 핵심 구성 요소 중 하나
    • 파일 시스템은 다양한 종류가 있고, 하나의 컴퓨터에서 보조기억장치마다 다른 파일 시스템을 사용할 수 있다.
  • 보조기억장치에 파일 시스템을 적용하려면 두 단계를 거쳐야 한다. 첫 번째 단계는 파티셔닝이고, 두 번째 단계는 포매팅이다.
    • 파티셔닝 (partitioning) : 저장 장치의 논리적인 영역을 구획하는 작업으로, 용량이 큰 저장 장치를 용도에 따라 하나 이상의 논리적인 단위로 구획한다. 이렇게 구획된 논리적인 영역을 파티션이라고 한다.
    • 포매팅 (formatting) : 파티셔팅된 보조기억장치에 어떤 파일 시스템을 적용하는 과정이다.
 

파일 할당하기

  • 운영체제는 파일과 디렉토리를 블록 단위로 읽고 쓴다.
    • 하나의 파일이 보조기억장치에 저장될 때에는 하나 이상의 블록에 걸쳐 저장된다.
    • 가령, 하드디스크의 가장 작은 저장 단위는 섹터이지만, 하나 이상의 섹터를 묶어 블록으로 칭하고 여기에서 파일과 디렉토리를 관리한다.
      • 파일 시스템이 모든 섹터를 관리하기에는 개수가 너무 많고 크기도 작기 때문이다.
  • 파일을 보조기억장치에 할당하는 방법에는 크게 두 가지가 있다.
    • 연속 할당
    • 불연속 할당 → 연결 할당, 색인 할당
 

연속 할당 (Continuous Allocation)

보조기억장치 내 연속적인 블록에 파일을 할당하는 방식으로, 구현이 단순하지만 외부 단편화가 발생할 가능성이 있다.

연결 할당 (Linked Allocation)

외부 단편화 문제를 해결하기 위해, 파일이 저장되는 블록마다 그 다음에 파일이 저장되는 블록의 번지를 저장하게 한다. 블록 구조가 연결 리스트 자료구조의 노드 구조와 유사하다.
  • 한계
    • 파일의 어느 부분부터 접근하더라도, 반드시 첫 번째 블록부터 하나씩 순서대로 읽어야 한다.
    • 하드웨어 고장이나 오류로 인해 특정 블록이 접근 불가능한 상태가 되었을 경우, 그 블록 이후의 블록들에 접근할 수 없다.
    • → 이를 변형한 시스템이 FAT 파일 시스템이다. (후술)

색인 할당 (Indexed Allocation)

블록 일부에 다음 블록 주소를 표현하는 방식인 연결 할당과 달리, 파일의 모든 블록 주소를 색인 블록 (Index block)이라는 하나의 블록에 모아 관리하는 방식이다.
→ 색인 블록에는 접근하고자 하는 파일의 여러 블록들이 위치한 인덱스들이 저장되어 있어, 이 인덱스들을 참고하여 블록들에 접근함으로써 결과적으로, 파일에 접근할 수 있다.
 

파일 시스템

FAT 파일 시스템

USB 메모리, SD 카드와 같은 저용량 저장 장치에서 널리 사용된다.
  • FAT 파일 시스템의 기반은 연결 할당이다. 연결 할당의 문제점은 블록 내부에 다음 블록의 주소를 저장했다는 것이다. 때문에 특정 파일에 접근하려면 여러 개의 블록들을 순차적으로 접근해야 하며, 이 블록들 중 어느 하나라도 문제가 생기면 파일에 접근할 수 없게 된다.
  • 다음 블록에 접근하려면 어느 블록에 반드시 접근해야 하는 문제점을 해결하려면, 각 블록에 포함된 다음 블록의 주소들을 한데 모아 테이블 형태로 관리하면 된다.
    • 이러한 테이블을 파일 할당 테이블 (FAT; File Allocation Table)이라고 한다.
  • FAT 파일 시스템에서 FAT는 파티션의 앞부분에서 만들어진다.

유닉스 파일 시스템

  • 유닉스 파일 시스템의 기반은 색인 할당이다. 유닉스 파일 시스템에서는 색인 블록을 i-node라고 부른다. i-node에 파일을 구성하는 블록들을 모두 포함하여 관리한다.
  • i-node의 구조
    • 특징
      • 15개의 블록으로 구성되어, 0~14번째 순번으로 나뉜다.
        • 크게 0~11번째 / 12번째 / 13번째 / 14번째로 들어가는 데이터의 규모가 달라진다.
        • 대부분의 파일은 i-node 하나에 모두 담을 수 있다.
      • i-node들이 모여 있는 영역이 파일 시스템 내부에 별도로 존재한다.
    • 블록 세부사항
      • 0~11번째 블록 : 데이터가 위치한 주소를 저장하고 있다.
      • 12번째 블록 : 단일 간접 블록. 여러 개의 데이터가 위치한 주소를 가리킨다.
      • 13번째 블록 : 이중 간접 블록. 여러 개의 단일 간접 블록을 가리킨다.
      • 14번째 블록 : 삼중 간접 블록. 여러 개의 이중 간접 블록을 가리킨다.

그 외 파일 시스템들

  • NTFS (윈도우 NT 커널)
  • EXT (리눅스 커널)
  • 저널링 파일 시스템
    • 컴퓨터가 파일 시스템을 변경하는 도중 예기치 못한 상황이 발생해 전원이 강제로 종료되면 파일 시스템이 손상될 수 있다.
    • 저널링 파일 시스템은 작업 로그를 통해 진행중인 작업에 대한 상태를 기록한다. 작업 로그는 파일 시스템의 로그 영역에 별도로 존재한다.
      • 작업을 수행하기 직전에, 작업 로그에 파티션의 로그 영역에 수행하는 작업에 관한 로그를 남긴다.
      • 로그를 남기고 작업을 수행한다.
      • 작업이 수행되면 로그를 삭제한다.
    • 시스템이 강제로 종료되면, 다시 켜질 때 로그 영역을 읽어 강제 종료될 당시 어떤 작업을 수행 중이었는지 확인하고 해당 작업을 완료한다.
    • 대부분의 현대 파일 시스템은 저널링 파일 시스템을 지원한다.
 

마운트

유닉스, 리눅스를 비롯한 POSIX 계열 운영체제에서 다른 저장 장치의 파일 시스템을 다른 파일 시스템에 편입시켜, 해당 저장 장치에 접근할 수 있도록 하는 것을 마운트라고 부른다.

문제풀이

notion image
notion image

혼공학습단 9기 후기

필자는 작년에 컴퓨터구조와 운영체제 모두 들었다. 그럼에도 이번 혼공학습단에 지원하고 6주 간의 과정을 마치게 된 계기에는 다가오는 기사 자격증 시험과 졸업시험, 그리고 각종 취업 준비를 위한 기본기를 닦기 위함이 제일 컸던 것 같다.
학교에서 다루지 않았던 부분들도 일부 있었는데, 이번 혼공컴운 진도를 나가고 주차마다 공부했던 내용들을 노션에 적고, 이를 페이스북 채널에 공유하는 과정에서 채워나갈 수 있었다. (노션 블로그 배포하는 법을 혼공학습단 시작하기 얼마 전에 배웠는데 잘 써먹고 있다 ㅎㅎ)
전체적으로 그동안 배웠었던 부분들을 다시 정리하고, 책에 있는 내용 바탕으로 스스로 설명하면서 이해하려고 노력하니 이해가 잘 가는 부분들도 많았다. 그리고 방학 동안에는 세워놓았던 계획도 잘 안 지키게 되고 그럴 때가 많은데, 이번 혼공학습단 과정만큼은 한 주도 빼먹지 않고 완주할 수 있었다. 아무래도 마감일이 있었기에, 그리고 우수혼공족 시상이 주마다 있었기에 더 열심히 임할 수 있었지 않았나 하는 생각이 든다.
아무쪼록 혼공족장님, 그리고 페이스북 채널에 계신 많은 혼공족 여러분들. 이번 혼공학습단 9기에서 다들 처음 뵈었는데 그동안 고생 많으셨습니다. 올해는 다들 계획하신 대로 잘 흘러가시길 바랄게요. 고맙습니다 :)