안녕하세요. 회사와 함께 성장하고 싶은 KOSE입니다.
이번 포스팅은 가상메모리에 대해서 정리하도록 하겠습니다.
1. 하드웨어와 제어구조
- 프로세스의 모든 메모리 참조는 논리주소이고, 이 주소는 프로세스 수행 시간에 동적으로 물리주소로 변환됩니다.
- 프로세스는 스와핑으로 다시 주기억장치에 적재될 때, 이전 위치가 아닌 다른 위치에 저장될 수 있습니다.
- 프로세스의 주소공간은 여러 블록으로 분할될 수 있고, 프로세스가 수행 중 이 블록들은 주기억장치의 연속된 영역에 위치할 필요가 없습니다.
2. 가상메모리 용어 정리
가상메모리 | 보조기억장치를 주기억장치처럼 주소지정 가능하게 만든 저장공간 할당체제 프로그램이 메모리를 참조할 때, 사용하는 주소는 메모리 시스템이 물리메모리의 특정 위치를 식별할 때 사용하는 주소와 구별 가상메모리의 크기는 주소지정체제와 보조기억장치의 가용 크기에 제한 |
가상주소 | 주기억장치처럼 참조될 수 있도록 가상메모리의 특정위치에 배정된 주소 |
가상주소공간 | 특정 프로세스에 할당된 가상 주소 영역 |
주소공간 | 특정 프로세스가 접근할 수 있는 메모리 주소 영역 |
실주소 | 주기억장치 상이 특정 저장위치의 주소 |
3. 주기억장치에 프로세스의 일부 블록(페이지, 세그먼트) 적재의 효과
수행 프로세스 과정
- 프로세스의 적재집합은 프로세스의 코드나 데이터 중 임의 시점에 주기억장치에 적재되어 있는 부분을 의미합니다.
- 처리기는 세그먼트테이블이나 페이지테이블을 이용하여 프로세스의 참조 주소가 적재집합에 포함되어 있는지를 파악합니다.
- 주기억장치에 적재되지 않은 논리주소가 참조될 경우, 처리기는 메모리 접근 오류 인터럽트를 발생시킵니다.
- 인터럽트 된 프로세스를 블록 상태로 둔 후, 디스크로부터 입출력 처리를 마친 후 블록된 상태를 재개합니다.
이러한 과정은, 보다 많은 프로세스를 주기억장치에 유지하고, 주기억장치보다 큰 프로세스를 수행할 수 있도록 합니다.
4. 페이징
가상 메모리는 전통적으로 프로세스별 페이지테이블이 설정됩니다. 페이지테이블 항목에는 해당 페이지가 메모리에 적재되어 있는지 구분할 수 있도록 비트(존재비트 P)가 존재해야 합니다. 페이지테이블 항목은 변경비트 M을 가지는데 해당 페이지가 메모리에 적재된 후 그 내용이 변경되었는지 여부를 나타냅니다.
페이지테이블 구조
- 프로세스가 수행될 때, 프로세스를 위한 페이지테이블의 시작 주소가 특정 레지스터에 저장
- 가상주소의 페이지 번호를 테이블의 인덱스로 사용하여 페이지테이블의 항목 선정
- 페이지가 적재된 프레임 번호를 얻음
- 프레임번호 + 가상주소의 오프셋과 결합되어 물리주소 구성
전통적인 페이지 테이블 구조
32비트 주소 체계에 적용 가능한 2단계 구조의 페이지 처리 방식은 다음과 같습니다.
여기서, 4KB(2^10 * 2^2) * 4MB(2^20 * 2^2) = 4GB(2^32 * 2^2) 이므로 다음과 같은 2단계 구조를 만들 수 있으며
전체 가상 주소 공간 2^32 / 페이지 크기 2^12를 하면 2^20의 페이지 수를 구할 수 있습니다.
2^20의 2^10(10 비트)은 루트 페이지 테이블 역할을 수행하고 나머지 2^10은 루트 페이지의 하위 페이지로 가상메모리 상에 유지됩니다.(프로세스가 적재되면 주기억장치로 루트 페이지 혹은 일부가 적재될 수 있습니다. -> 요구 페이징) 가상 페이지의 처음 10비트는 루트 페이지에 대한 인덱스로 쓰여 사용자 페이지테이블이 저장된 페이지를 위한 PTE를 찾아주며 (2^10), 여기서 찾은 값이 인덱스로 쓰여 가상주소에 참조될 실제 페이지를 위한 PTE를 찾게 합니다. 여기서 프레임 번호를 얻을 수 있으며 12비트의 오프셋과 합쳐져 주기억장치의 페이지프레임을 구할 수 있습니다.
역페이지 테이블 구조
앞서 정의한 전통적인 페이지테이블 구조에서는 가상 페이지수에 비례하여 PTE가 증가하게 되는데, 이를 주메모리에 적재해야 된다는 점에서 주기억장치에 많은 무리를 줄 수 있습니다. 이를 해결하기 위한 방법이 역페이지 테이블 구조입니다. 역페이지 테이블 구조의 저장 방식은 다음과 같습니다.
- 가상주소 중 페이지번호 부분은 간단한 해시 함수를 통해 특정 해시 값으로 사상됩니다.
- 해시값은 역페이지 테이블에 대한 인덱스로 쓰이고, 역페이지테이블은 페이지테이블의 항목들로 구성됩니다.
- 페이지테이블 항목이 가상메모리의 페이지 당 하나씩이 아니라 실기억장치의 페이지프레임당 하나씩 설정되므로 프로세스의 수나 지원되는 가상 페이지 수와 상관없이 주기억장치의 일정 부분만이 테이블 설정에 쓰입니다.
- 하나 이상의 가상주소들이 동일한 해시테이블 항목으로 사상될 수 있으므로 연결 기법을 통해 체인 기법을 활용합니다.
저는 역페이지 테이블 구조 2가지가 이해가 되지 않았습니다.ㅜㅜ
(하단에 게시되는 글을 제가 이해한 바를 정리한 내용이므로 사실과 다를 수 있습니다.)
먼저 실주소를 찾는 과정을 이해하는데 어려움을 겪었습니다.
예를 들어 운영체제가 프로세스A에 대한 가상 주소를 실주소로 매핑하길 원할 때, 단순히 페이지 번호로 어떻게 실주소를 매핑할 수 있는가입니다. 즉, 페이지 번호는 많은 프로세스에서 겹칠 수 있는데 역페이지테이블에서 프로세스 ID를 제공하더라도 여러 개의 체인으로 연결된 매핑값을 모두 실주소로 변환한 후 실주소에 접근하여 해당 프로세스가 운영체제가 요구하는 프로세스 A와 같은지 파악해야 하지 않는가입니다
이 문제에 대한 답변은 여러 블로그와 GPT를 통해 찾을 수 있었고 해당 절차는 다음과 같습니다.
운영체제는 현재 실행 중인 프로세스 A에 PID를 얻습니다. 가상 주소를 통해 페이지 번호를 획득한 후 해시함수에 프로세스 A의 PID와 가상 주소를 적용합니다. 만약 찾았다면 리턴하고, 해당 PID가 일치하지 않는 경우 체인을 활용하여 주소를 찾습니다. 역페이지테이블에서 해당 해시값을 바탕으로 실주소의 프레임 번호를 찾아 가상 주소의 오프셋과 결합하여 실주소를 얻습니다.
두번 째는 페이지테이블 항목이 가상메모리의 페이지 당 하나씩이 아니라 실기억장치의 페이지프레임당 하나씩 설정된다는 의미가 이해가 되지 않았습니다. 이에 대한 자료를 찾아본 후 제가 이해한 바는 다음과 같습니다.
페이징 작업을 수행할 때 주기억장치도 페이지 프레임을 적용합니다. 이때 가상 페이지 블록과 동일한 크기로 주기억장치도 물리 메모리를 분할하게 되는데, 분할된 각 페이지프레임에 대해 페이지테이블을 적용합니다. 이를 통해 다시 페이지테이블과 역페이지테이블을 이해하면, 페이지테이블의 경우 가상 주소 공간을 페이지 범위로 나누고 각 페이지에 대해 테이블 엔트리를 설정하기에 프로세스별로 PTE가 생성되게 됩니다.
역페이지테이블은 프로세스가 실행될 때, 필요한 가상 메모리 페이지들은 디스크 스왑 영역에 위치하고 프로세스가 해당 페이지에 액세스 하는 경우 페이지폴트가 발생하여 주기억장치에 스왑인 됩니다. 이 과정에서 역페이지 테이블에 페이지에 대한 정보, 프로세스 ID 등의 정보를 입력하게 됩니다. 따라서, 페이지 번호와 오프셋을 통해 가상 주소를 실주소로 매핑할 수 있게 됩니다. 즉, 프로세스 별 PTE를 적재하는 것이 아니라, 주메모리에 있는 페이지프레임에 역페이지테이블을 구성하여 적재하는 것입니다.
5. TLB(Translation Lookaside Buffer)
원칙적으로 모든 가상메모리 참조는 두번의 물리 메모리 참조를 수반하므로 두 배의 메모리 접근 시간을 갖게 합니다.
가상메모리 방식은 페이지테이블 항목들에 대한 특수 고속 캐시를 사용하는데, 이를 TLB라고 부릅니다. TLB는 가장 최근에 참조된 페이지테이블의 항목을 유지합니다.
TLB의 작동 구조
- 시작
- CPU가 TLB를 검사
- TLB에 페이지 테이블 항목이 있다면 CPU가 물리 주소를 생성
- 없다면, 페이지 테이블에 접근하여 주기억 장치에 페이지 테이블 확인 (존재비트 1 or 0)
- 있다면(존재비트 1), TLB를 갱신한 후 CPU 물리 주소를 생성
- 만약 주기억 장치에 페이지가 없다면 '페이지 폴트'가 발생하여 운영체제가 CPU에게 디스크로부터 페이지를 반입하도록 명령
- CPU가 입출력 하드웨어를 활성화하고 드스크로부터 주기억장치로 페이지를 스왑인
이 부분에서 혼란이 왔던 부분은 실제 페이지테이블에서 페이지 번호를 조회하는 것과 TLB에서 페이지 번호를 조회하는 것이 결국 같은 메커니즘으로 적용되는 것이 아닌가라는 의문이었습니다.
하지만 실제 메커니즘은 많이 달랐습니다. 앞 서 페이지테이블은 일부가 주기억장치에 저장된다고 설명하였습니다. 만약 페이지폴트가 발생하지 않는 상황하에서 가상메모리의 실주소를 찾는 과정은 주기억장치에 접근해야 하므로 속도가 더딜 수 있습니다.
TLB는 CPU 하드웨어에 접근하여 만약 TLB 페이지테이블에 항목이 있다면 이미 주기억장치에 스왑인 하면서 TLB를 갱신한 것을 의미하기 때문에 물리주소를 바로 얻어올 수 있습니다.
만약, 페이지폴트가 발생한다면 디스크로부터 주기억장치로 필요한 페이지를 전송하여 적재하고 TLB를 갱신합니다. 이러한 과정을 통해 최근 참조된 페이지테이블에 값은 TLB에 적재되어 주기억장치를 매번 들려서 물리주소를 찾지 않더라도 빠른 고속 처리를 가능하도록 합니다.
6. 페이지 크기
페이지 크기는 그 양에 따라 페이지 폴트 발생률이 달라질 수 있습니다.
페이지 크기가 작은 경우
일반적으로 페이지 크기가 작다면 페이지폴트의 경우 지역성의 원리에 따라 한 프로세스가 활용할 수 있는 페이지들이 상대적으로 많아집니다. 이는 곧 페이지폴트 수를 줄이는 효과를 얻을 수 있습니다. 페이지 폴트의 수를 줄이는 이유는 다음과 같습니다.
- 공간 지역성: 프로세스는 일반적으로 코드와 데이터의 일부 영역에 집중되어 실행됩니다. 페이지 크기가 작으면 주기억장치에 적재된 페이지가 필요한 데이터와 코드만 포함하게 되므로 더 좋은 공간 지역성을 달성합니다.
- 메모리 사용의 효율성: 작은 페이지 크기를 사용하면 페이지 내부의 미사용 메모리 공간이 줄어들고 메모리 사용 효율성이 향상됩니다. (내부 단편화 감소)
< 페이지 크기가 작으면 주기억장치에 적재된 페이지가 필요한 데이터와 코드만 포함?>
페이지 크기가 작아지면, 각 페이지에 포함된 데이터와 코드가 더 밀집되어 있습니다. 이렇게 되면 주기억장치에 적재된 페이지가 프로세스가 필요로 하는 데이터와 코드만 포함하게 됩니다. 앞 서, 페이지 크기가 작으면 주기억장치에 적재된 페이지가 필요한 데이터와 코드만 포함하게 된다는 의미는 실제 프로세스가 주기억장치에 적재될 때 페이지 크기가 클 경우 불필요한 데이터도 함께 적재될 수 있지만, 페이지 크기가 작을 경우 반드시 필요한 소스만 적재될 수 있기 때문에 효율적으로 사용할 수 있다는 의미입니다.
하지만, 반드시 페이지폴트가 감소하는 것은 아닙니다.
페이지 크기가 작을 때는 페이지 수가 증가하게 됩니다. (32비트 가상 주소 공간을 고려하면, 2^12의 페이지 크기가 있다면 32 - 12 = 20 즉 2^20만큼의 페이지 수가 필요합니다)
이는 곧 페이지 테이블이 증가하는 문제를 발생시키고, 멀티프로그래밍 환경에서 큰 프로그램을 수행하는 활성 프로세스의 페이지테이블 중 일부가 주기억장치에 적재되지 못하고 가상메모리 상에 있어야 합니다. 즉 이 경우는 반대로 페이지 폴트 발생률을 높일 수 있습니다.
페이지 크기가 클 경우
페이지 크기가 큰 경우 페이지 폴트 발생률은 증가할 수 있습니다. 페이지 크기에 따라 비례하여 페이지 수는 작아지므로 개별 페이지들은 최근 잠조로부터 멀리 떨어진 위치를 포함하게 됩니다. 이는 지역성의 원리에 따르면 공간 밀집도가 낮아지게 되므로 페이지 폴트 발생 확률을 높입니다.
페이지 크기가 프로세스 전체 크기와 근접해 갈 경우
이 경우 하나의 페이지에 프로세스 전체를 적재할 수 있으므로 페이지 폴트 발생 빈도가 감소하게 됩니다.
7. 정리하며
가상 메모리를 사용할 경우 모든 주소 참조는 실행 중에 실주소로 변환되는 논리적 띄게 됩니다. 가상 메모리의 도입으로 주기억장치에 가해지는 부담을 효과적으로 줄일 수 있습니다. 이러한 가상 메모리의 용어, 페이지를 정리하며 정말 많은 점을 배울 수 있었고 단순히 논리적 참조로만 알고 있었던 과거에 저를 반성할 수 있게 되었습니다.
이해가 되지 않는 부분이 너무 많았고 하나씩 이해하는 과정에서 정말 많은 시간이 흘렀지만 가상 메모리가 어떠한 수행 절차로 실주소로 변환되는지 배울 수 있었고, TLB로 최근 참조한 페이지테이블에 대한 고속 캐시 효과를 얻을 수 있는 점도 정리할 수 있었습니다.
사실과 무관한 정보도 있을 수 있습니다. 이 부분은 계속 반복 학습하여 수정해 나가겠습니다.! 피드백 주시면 바로 배우겠습니다.
감사합니다.!
자료 출처: 운영체제 제 8판 내부구조 및 설계원리
그림 출처: https://velog.io/@gndan4/OS-%EA%B0%80%EC%83%81-%EB%A9%94%EB%AA%A8%EB%A6%AC
'OS' 카테고리의 다른 글
[OS] 단일처리기 스케줄링 (0) | 2023.04.25 |
---|---|
[OS] 메모리 관리 (0) | 2023.04.19 |
[OS] 상호 배제를 위한 모니터 (0) | 2023.04.19 |
[OS] 세마포어(Semaphores) (0) | 2023.04.18 |