수업/운영체제

Operating System - Segmentation[Memory Virtualzation](5)

MinDDokDDok 2022. 12. 22. 10:40

Segmentation

--> Motivation? base and bound approach 비효율성

--> 연속적인 물리적 메모리 공간에 매핑해야 한다는

--> 1. Wasted Memory 메모리 낭비

--> 2. Big Address Space Not Supported 여러 프로세스가 들어오면 못들어간다

--> 3. Duplicated Code Section 수행에 필요한 공통적인 코드가 겹치기에 공간이 낭비

 

Segmentation?

--> 주소공간을 세그먼트로 나누고 각각의 세그먼트들을 독립적인 물리적 메모리에 매핑시키는 방법

No segmentation
Segmentation

세그먼트는 특정길이의 주소공간에서 연속적인 부분

--> Locally-defferenct segment : Code, Stack, Heap 존재

 

구현?

명시적 접근(Explicit Approach)

--> 가상주소의 상위공간 비트를 기준으로 주소공간을 세그먼트로 자름

--> MSB(Most Significant Bit - 최상위 비트), LSB(Least Significant Bit - 최하위 비트)

1. 예에서 2비트는 다른 세그먼트로 분리되었나?

--> Segment ID값으로 분리되기위해 --> 만약 비트라면?? 코드와 영역이 같은 세그먼트로 합쳐질 --> ID값으로 분리할 없기에

2. 12비트는 Offset으로 사용되었나?

--> 하나 메모리 주소가 가리키는게 1byte, 오프셋이 12bit 이루어져 있으므로 2^12byte 가리킬 있다

--> 26K + 104만큼이 Offset

--> 가리키는 물리적 주소의 Base 26K이고, 여기서 논리적 주소값을 더한게 Offset 만큼이므로 --> Offset 000001101000 --> 2^6 + 2^5 + 2^3 = 104만큼 차지

--> Offset 가리키는 논리적 주소

--> Offset 104 바운드(2K) 보다 적으니 정상적 --> 만약 정상적이지 않으면 exception 발동

 

만약 code sharing 되는 library 코드를 어느 프로세스가 바꿔놓는다면?? 안된다

--> read 가능하지만 write 불가하게 protection 거쳐야

 

스택은 뒤로 증가( 밑으로 증가) - dynamic하기에

--> Extra Hardware 필요 --> 하드웨어가 세그먼트가 어느방향으로 커지는지 체크함

--> 해당 비트가 1이면 위로(positive direction), 0이면 아래로(negative direction)

 

코드, , 스택 각각의 base/bound register 필요(PCB내에 존재 - OS 관리)

stack 보수를 취해서(negative) - 위에서 아래로 가면서 점유

--> Stack 주소의 가장 높은부분에 위치하기에 아래로 가면서 점유하기에 Offset 2 보수를 취해주어야 한다

Segment ID를 통해 가리키는 Segment를 지정한 후, 후에 Offset이 가리키는 값 만큼 이동한 곳이 physical address의 위치이다(여기선 Stack이므로 Offset값에서 2의 보수를 취한 010111111111로 해석)

해당 상황에서 Offset 보수를 취하면? 010111111111 = 1535 --> Bound(2K = 2000)보다 아래기에 ok

 

공통으로 쓰이는 코드?

Code Sharing - ex. library --> 여러 프로세스가 공유하는 코드이기에, 임의의 프로세스가 이를 변경해서는 안된다 --> 권한을 주는 방식으로(permission bit, protection bit)

--> Protection bit 필요하다! read 가능하도록 도와줌(Permission bit 둠으로써)

 

하드웨어는 Implicit Apporach 암시적인 접근으로 주소가 어떻게 생성되었는지 있다

--> PC 의해 생성? --> Code segment

--> Stack이나 base pointer 기반을 둔다? --> Stack Segment

--> 이외 다른 주소 --> Heap Segment

 

Segmentation 문제

OS Context Switch 한다면

--> Segment registers(base and bound registers pair) 저장되고 관리되엉 ㅑ한다

세그먼트 사이즈를 바꾸는 방법? 많은 heap 영역 - malloc() 혹은 sbrk() system call

 

물리적 메모리에서 free space 관리하는 방법?

--> OS 물리적 메모리에서 세그먼트 별로 free space 찾을 있어야

--> Fragmentation

 

Fragmentation

--> 전체 여유공간은 되는데, 쪼개져 있기에 메모리 공간 하나에 모여져있지 않고 파편화(fragmentation) -- 총량은 24kb, freespace 16, 4, 4 --> 20kb 들어온다면? --> compaction 거쳐 묶어서 재배치

--> Compaction 사용되지 않는 이유 --> Costly, 비싸다

--> 프로세스를 멈추고, 데이터를 카피해둔 , 세그먼트 레지스터 값을 바꾸어야 한다

--> 이미 메모리에 써져있던 영역을 다시 읽고 다시 써야한다는 --> cpu 성능은 메모리 접근해서 읽고 쓸때 떨어지므로 - 성능이 떨어진다

--> 이러한 것을 없애기 위해서 나온게 paging이기도 --> 정해진 크기별 세그먼트로 나누어 관리해 external fragmentation 방지하는

--> 근데 paging Internal Fragmentation이라는 문제점이 있다

--> 페이지 단위로 매핑 --> 페이지 단위 - 단일 사이즈로

--> 15kb 요청 - 8kb 페이지 2 할당 --> 1kb 잉여 메모리 공간

Segmentation 세분화 정도 - pdf 보기 중요하진 X

Fine-Grained - 작게작게 관리

Coarse-Grained - 큼직큼직 관리

 

요약

Segmentation 물리적 메모리 할당에서 효율적

--> No longer wasted Memory

--> Big Address Space Supported

--> Code Sharing Supported

 

Segmentation 문제점

--> External Fragmentation

--> 해결책 : Paging

--> Paging 문제점 - Internal Fragmentation

 

heap영역을 할당하는 API - malloc()

만약 30-byte size 힙이 있다고 가정,

malloc(10)해서 heap영역의 10bytes 할당(allocate) --> 10 할당 요청? --> 근데 사용중임(10~20)

--> 20 ~ 30부분에 재할당해서 20~30 used 바뀌고, 이후 5 할당 요청

0~10 중에서 split 5 ~ 10 할당 --> 이후에 사용하면 free(5)

만약 heap space 넘어서 수행된다면? --> sbrk(10)라는 시스템콜 --> OS 10바이트끼리 뭉쳐서 20byte 사이즈가 돌아갈 있도록 바꿔준다

그러면 malloc(20)해도 돌아갈 있다

--> 근데 논리적으로 같은 공간에 두는 것일 물리적으로 같이 만들어두는 것은 아님

sbkr()는 따로 분리된 Physical Memory를 논리적으로 합친 것에 불과

만약 메모리의 chunk( 덩어리) 요청되면, 라이브러리는 요청을 감당할만하게 충분히 사이즈의 chunk 찾는다 --> Library Chunk 두개로 Split (하나는 request 처리용, 하나는 free chunk 남겨둠) 그리고 list free chunk 사이즈를 shrink(축소)

예시)

사이즈를 4KB, 32비트 아키텍쳐를 사용중이라고 가정

32bit --> 크기가 4Byte / 64bit 크기가 8Byte

번째 --> 4096Byte(4KB) - 4Byte - 4Byte = 4088Byte

번째 --> 4096Byte(4KB) - 4Byte - 4Byte - 100Byte(alloacted 영역) - 4Byte - 4Byte = 3980Byte

4096(4KB) - 100 - 100 - 100 - 8 - 8 - 8 - 8 = 3764byte

managing free space - free space 제공할 것인지에 대한 기준

 - best fit

 : 요청한 크기와 가장 유사한 크기를 찾아서 제공 - free chunk 요청한 크기와 맞거나, 조금 정도

 --> 가장 적은 차이로 남기기 위해

 

 - worst fit

 : 제일 잉여메모리 남기는, 가장 차이가 크기 제공 - free chunk 가장 크기

 --> 제공할 있도록 free space 가능한 많이 갖기 위해서 쓰는

 

 - First fit

 : 요청하는거 보다 크면 무조건 바로제공 - 요청하는 보다 first chunk 바로 제공

--> 속도, 빠른 할당

 

 - Next fit

 : 요청하는거 보다 크면 제공 --> 목록을 구걸하는게 아닌 보고있던 것을 바로 제공

Slab Allocator

--> 자주 쓰이는 것들을 분석해 메모리에 담아두는 정책

--> 자주 쓰이는 ? 보통 캐시 메모리에 있다

--> 메모리에 최소한 접근하는데 그치기 위해서, 가장 많이사용 되는 적은 용량의 빠른 메모리에 올려논 캐시 메모리

--> , 캐시 메모리에 있는 것들은 빈번히 사용되는

--> 캐시 메모리에 있는 데이터들을 보고, 그에 맞게 크기단위를 구분짓는다

Buddy Allocation

--> Free space 제공하되, 가능한 나중에 return 되었을 쉽게쉽게 합쳐서 메모리공간을 쉽게 확보하겠다는 목적으로

--> 그니까 64kb 있는데 7kb만큼 요청이 온다 --> 통채로 안주고 나누고, 나누고, 나눠서 8kb만큼만 주고 끝낸다

--> 8kb free 되어 return된다 --> 병합 --> 그냥 8kb 빈거랑 병합, 16kb빈거랑 병합, 32kb 빈거랑 병합 이런식으로 다시 되돌아가는 --> 그렇다고 해서 똑같은 사이즈랑 병합하진 않음 --> 보통 그래도 2진트리 방식으로 하긴함

--> 실제로 많이사용