유저 모드( User Mode )

 

  • 유저 모드( User Mode )는 프로그래머가 작성한 프로세스 코드만을 실행하기 위한 모드이며 해당 모드에서는 커널 영역에 있는 어떠한 리소스에도 접근할 수 없습니다.




커널 모드( Kernel Mode )

 

  • 커널 모드( Kernel Mode )는 유저 영역 및 커널 영역과 같은 모든 리소스에도 접근할 수 있는 상태를 말하며 파일 I/O 또는 입출력 장치에 접근하기 위해 시스템 함수를 호출할 경우 커널 모드로 전환됩니다. ( 커널 모드로 전환되면 플래그 레지스터의 슈퍼 바이저 플래그가 1이 됩니다. )




시스템 호출( System Call )이란?

 

 

  • 운영체제 자원 및 입출력 장치에 접근하기 위해서는 반드시 시스템 호출( System Call )을 통해서만 운영체제로부터 서비스를 제공받을 수 있습니다.

 

  • 시스템 호출은 일종의 소프트웨어 인터럽트로서 운영체제는 커널 모드로 전환되고 현재 CPU 작업에 대한 레지스터 정보를 백업하고 인터럽트 신호에 대응하는 인터럽트 루틴을 수행한 뒤 기존에 백업해놨던 레지스터 정보를 CPU에 다시 업로드합니다. 이러한 일련의 과정 때문에 커널 모드로의 전환이 성능 저하의 원인이 되며 최대한 시스템 호출을 줄여서 커널 모드로 전환되는 것을 줄여야합니다.




유저 모드와 커널 모드를 구분하는 이유

 

  • 프로그래머가 작성한 코드에 문제가 생길 경우 해당 프로세스 내부에 있는 쓰레드가 멈추거나 프로세스 자체가 다운되는 것에 그칩니다. 만약, 프로세스가 커널 리소스에 직접적인 접근이 가능해서 문제를 야기할 경우 해당 OS에서 실행되고 있는 모든 프로세스에 악영향을 미칠 수 있습니다. 그렇기 때문에 유저 모드와 커널 모드를 구분하여 프로그래머가 작성한 프로세스가 커널 리소스에 직접적인 접근을 완전히 막고 시스템 호출을 사용한 간접적인 접근만을 허용함으로써 OS의 안전성을 높일 수 있습니다.




가상 메모리( Virtual Memory )란?

 

  • 가상 메모리는 메인 메모리의 물리적인 주소 체계를 사용하지 않고 가상의 주소 체계를 사용하여 프로세스의 독립적인 가상 메모리 주소 공간을 확보하는 기술을 말합니다. 그렇기 때문에 메모리에 접근할 때마다 MMU를 통해 가상 메모리 주소에 맵핑된 물리 메모리 주소로 변환하여 접근합니다.




가상 메모리 장점

 

  • 보조 기억 장치의 페이징 파일을 통해 사용할 수 있는 메모리를 확장하여 보다 더 많은 메모리를 사용할 수 있습니다.

  • 가상 메모리 주소 체계를 사용함으로써 프로세스간의 직접적인 메모리 접근을 방지하여 시스템 안정성을 확보할 수 있습니다.

  • 프로세스 실행에 필요한 메모리 공간을 점진적으로 확보해가기 때문에 프로세스의 실행 속도를 높이고 메모리 사용량을 절약하고 단편화를 줄일 수 있습니다.

  • 동일한 프로세스를 여러개 실행 했을 때 Copy On Write 기법을 이용해서 서로 동일한 가상 주소를 사용하다가 메모리가 수정될 때 새로운 페이지를 확보하고 복사 후 수정하는 방식으로 메모리 사용량 및 프로세스 실행에 필요한 메모리 업로드 오버헤드를 절약할 수 있습니다.




가상 메모리 단점

 

  • MMU를 통해서 가상 메모리 주소를 물리 메모리 주소로 변환하는 작업이 필요합니다.

  • Fage Fault가 발생되었다면 보조 기억 장치에 있는 페이징 파일을 참조해서 페이징 스왑을 하는 작업이 필요합니다.




페이징( Paging )이란?

 

  • 페이징( Paging )이란 프로세스의 논리 주소 공간을 페이지라는 일정한 단위로 자르고, 메모리 물리 주소 공간을 프레임( Frame )이라는 페이지와 동일한 크기의 일정한 단위로 자른 뒤 페이지를 프레임에 할당하는 가상 메모리 관리 기법을 말합니다.




페이지 테이블( Page Table )이란?

 

 

  • 페이지 테이블( Page Table )에는 페이지 번호와 프레임 번호가 맵핑되어 있는 테이블로서 MMU( Memory Management Unit )가 가상 메모리 주소를 물리 메모리 주소로 변환할 때 참조하는 테이블입니다. 가상 메모리 주소와 페이지 테이블 덕분에 불연속적으로 프레임에 맵핑되어 있는 페이지를 연속적인 메모리처럼 사용할 수 있습니다.




페이지 테이블 베이스 레지스터( PTBR : Page Table Base Register )

 

  • 페이지 테이블 베이스 레지스터란 프로세스마다 가지고 있는 페이지 테이블 주소 값을 저장하는 레지스터입니다. 페이지 테이블 베이스 레지스터 데이터는 PCB에 저장되며, 프로세스 컨택스트 스위칭 때 다른 레지스터 데이터와 같이 CPU 레지스터 셋트에 업로드됩니다.




TLB( Translation Lookaside Buffer )란?

 

 

  • 메모리에 접근할 때마다 페이지 테이블을 참조하여 가상 메모리 주소를 물리 메모리 주소로 변환할 경우 메인 메모리 접근으로 인한 오버헤드가 발생됩니다. 이러한 오버헤드를 줄이기 위해 페이지 테이블에 대한 캐시 데이터를 TLB( Translation Lookaside Buffer )에 저장합니다. MMU가 가상 메모리 주소를 물리 메모리 주소로 변환할 때 가장 먼저 TLB를 참조하고 TLB에 원하는 물리 주소가 있는 경우를 TLB hit라 하고 없을 경우를 TLB miss 라고 합니다.




페이지 인( Page In )/페이지 아웃( Page Out )

 

  • 페이지 교체 알고리즘에 의해서 필요하지 않은 페이지들을 보조 기정 장치의 페이징 파일에 저장할 수 있습니다. 이것을 페이지 아웃( Page Out ) 이라고 하며, 지금 쓰레드 실행에 있어서 필요한 메모리가 페이징 파일에 있을 때 페이지 테이블에 맵핑시키는 것을 페이지 인( Page In )이라고 합니다.




메모리 주소에서 페이지 번호를 확인하는 방법

 

 

  • 접근하고자 하는 주소가 몇 번째 페이지인지 확인하기 위해서는 페이지 크기가 4KB라고 했을 때 위 코드에서 처럼 상위 bit를 페이지 번호로 사용하고 하위 bit를 페이지의 offset으로 사용할 수 있습니다.




페이지 테이블 엔트리( PTE : Page Table Entry )

 

  • 페이지 테이블 각 행마다 페이지 번호와 프레임 번호 정보만 있는것이 아니라 유효 비트, 보호 비트, 참조 비트, 수정 비트 등의 페이지 상태 데이터 정보 또한 관리하고 있습니다. 페이지 테이블의 행을 페이지 테이블 엔트리( PTE : Page Table Entry )라고 부릅니다.




유효 비트

 

  • 유효 비트는 해당하는 페이지가 물리 메모리에 맵핑되어 있는지를 확인할 수 있는 비트입니다. 만약 물리 메모리에 맵핑되어 있지 않다면은 Page Fault 예외가 발생됩니다.




보호 비트

 

  • 보호 비트는 해당하는 페이지의 읽기, 쓰기, 실행 권한에 대한 정보가 담겨져 있습니다. 읽기, 쓰기, 실행이 가능한지를 확인할 수 있습니다.




수정 비트 or 더티 비트

 

  • 수정 비트는 한 번이라도 페이지가 수정된적이 있는지에 대한 정보가 담겨져 있습니다. 만약, 한 번도 수정되지 않은채 페이지 아웃되었다면 페이징 파일을 수정할 필요 없이 새로운 페이지로 덮어 씌우면 되기 때문에 복사 오버헤드를 줄일 수 있습니다.




페이지 교체 알고리즘

 

  • 페이지 교체 알고리즘은 페이지를 맵핑할 수 있는 물리 메모리가 부족할 경우 페이지 교체 알고리즘을 통해서 아웃할 페이지를 선정하고 신규 페이지를 맵핑합니다.(OS 마다 사용하는 페이지 교체 알고리즘이 다릅니다.) 페이지 교체 알고리즘으로는 FIFO( First In First Out), LRU( Least Resently Used )등이 있으며 대부분의 OS들은 복합적으로 응용해서 발전시킨 페이지 교체 알고리즘을 사용합니다.




쓰레슁( Thrashing ) 현상이란?

 

  • 페이지 교체 알고리즘이 좋지 못하거나 물리 메모리가 부족하여 새로운 페이지를 맵핑할 수 있는 공간이 없을 경우 CPU 자원을 페이지 교체에 과소비하는 현상을 말합니다. 대부분의 경우는 물리 메모리 용량을 증가시킴으로써 해당 현상을 해결할 수 있습니다.




단편화( Fragmentation )이란?

 

  • 단편화(Fragmentation)란 메모리 관리 과정에서 발생하는 메모리 낭비 현상을 말합니다. 단편화는 외부 단편화와 내부 단편화가 있습니다.




외부 단편화( External Fragmentation )이란?

 

 

  • 외부 단편화는 연속 메모리 할당에 방식에서 할당 및 해제를 반복하여 발생되는 단편화입니다. 즉, 위 그림과 같이 현재 PROCESS D를 적재할 수 있는 가용 메모리 공간은 충분하지만 연속적이지 못하기 때문에 메인 메모리에 적재할 수 없는 상태를 말합니다.




연속 메모리 할당이란?

 

  • 프로세스 실행에 필요한 연속적인 메모리 공간을 메인 메모리에 그대로 적재하는 것을 말합니다. 이러한 연속적인 메모리 할당으로 인해서 아직 사용하지 않은 메모리까지 할당하게 되며 외부 단편화( External Fragmentation )까지 발생시키기 때문에 매우 비효율적인 메모리 할당 방식입니다.




내부 단편화( Internal Fragmentation )이란?

 

 

  • 페이징은 외부 단편화 문제를 해결할 수 있지만, 내부 단편화( Internal Fragmentation )라는 문제가 발생될 수 있습니다. 위 그림과 같이 실제로 필요한 메모리는 3KB이지만, 할당 단위가 4KB 페이지 단위이기 때문에 할당하면서 1KB의 내부 단편화가 발생됩니다. 이러한 단편화를 줄이기 위해서는 페이지 크기를 고려해야 하지만, 페이지 크기가 작을 수록 페이지 테이블 크기 그리고 페이지 스왑 현상이 빈번하게 발생될 수 있고, 페이지 크기가 너무 크다면은 위와 같이 내부 단편화의 크기가 커질 수 밖에 없기 때문에 적절한 페이지 크기를 사용해야 합니다.




CPU 스케줄링

 

  • CPU 스케줄링이란 스케줄링 알고리즘을 통해 선택된 쓰레드가 CPU 자원을 할당받아 실행될 수 있도록 하는 것을 말합니다. CPU 스케줄링 알고리즘의 종류는 다양하고 운영체제마다 서로 다른 스케줄링 알고리즘을 사용하고 있습니다.




CPU 스케줄링 알고리즘 종류

 

선입 선처리 스케줄링( FCFS : First Come First Scheduling )

 

  • 선입 선처리 스케줄링은 비선점형 방식으로 먼저 들어온 쓰레드를 순서대로 CPU 자원을 할당해주는 스케줄링 알고리즘입니다. 이러한 방식은 공정해 보일 수는 있으나 지금 당장 급하게 CPU 자원을 필요로 하는 쓰레드에게 먼저 CPU 자원을 할당해줄 수 없다는 단점이 있습니다.




최단 작업 우선 스케줄링( SJF : Shortest Job First Scheduling )

 

  • 최단 작업 우선 스케줄링은 CPU 사용 시간이 가장 짧은 순서대로 쓰레드에게 CPU를 할당하는 방식으로서 쓰레드가 너무 장기간 CPU 자원 할당을 기다리지 않도록 하기 위해 사용하는 스케줄링 알고리즘입니다. 이러한 방식은 CPU 자원을 오랫동안 사용하는 쓰레드들이 CPU 자원을 원활하게 할당받지 못하여 쓰레드 기아( Thread Starvation ) 상태가 될 수 있습니다.




라운드 로빈 스케줄링( Round Robin Scheduling )

 

  • 라운드 로빈 스케줄링은 레디큐에 Enqueue된 쓰레드 순서대로 타임 슬라이스만큼 CPU 자원을 할당하는 방식의 스케줄링 알고리즘입니다. 타임 슬라이스의 크기는 OS 마다 다르며 타임 슬라이스의 크기가 너무 클 경우 쓰레드가 지나치게 대기해야 하는 현상이 발생되며, 타임 슬라이스가 너무 짧을 경우 컨택스트 스위칭 비용이 커질 수 있습니다.




우선 순위 스케줄링( Priority Scheduling )

 

  • 우선 순위 스케줄링은 프로세스 우선순위 클래스와 쓰레드 우선 순위를 부여해서 가장 높은 우선 순위를 가진 쓰레드를 실행하는 스케줄링 알고리즘입니다. CPU 자원을 할당받아 실행중인 쓰레드보다 현재 레디 큐에 있는 쓰레드의 우선 순위가 높을 경우 레디 큐에 있는 쓰레드가 CPU 자원을 선점합니다. 이러한 방식은 빠른 응답을 요구하는 쓰레드가 빠르게 CPU 자원을 할당 받을 수 있지만 보다 낮은 우선순위를 가진 쓰레드들은 CPU 자원을 원활하게 할당받지 못하여 쓰레드 기아( Thread Starvation ) 상태가 될 수 있습니다. 이러한 방식의 단점을 해결하고자 우선 순위가 낮아서 CPU 자원을 오랫동안 할당받지 못한 쓰레드들에게 우선순위를 점차 높이는 에이징 기법을 같이 사용합니다.




다단계 큐 스케줄링( Multilevel Queue Scheduling )

 

 

  • 다단계 큐 스케줄링은 우선순위 스케줄링의 발전된 형태로서 우선 순위별로 레디 큐를 여러 개 사용하는 스케줄링 방식입니다. 높은 우선 순위 큐를 우선적으로 확인하여 스케줄링하는 방식이기 때문에 보다 편리한 스케줄링 방식입니다.




Windows 스케줄링 방식

 

  • OS 마다 스케줄링 알고리즘이 다르며 스케줄링 알고리즘을 복합적으로 사용하는 경우가 많습니다. Windows는 우선순위 선점형 기반의 라운드 로빈, 다단계 큐 스케줄링 등을 사용하고 있습니다.




명령어 사이클

 

  • 프로그램을 실행하기 위해서 메모리에서 명령어를 가져오고 실행하는 과정을 명령어 사이클( Instruction cycle ) 이라고 합니다.




인터럽트( Interrupt )란?

 

  • 인터럽트란 '방해하다.', '중단시키다.'라는 의미를 가지고 있습니다. CPU에게 현재 수행중인 작업보다 급하게 필요한 일을 요청해야 할 때 CPU에게 인터럽트 신호를 보내서 해당하는 인터럽트의 서비스 루틴을 수행하도록 합니다.




인터럽트 서비스 루틴( Interrupt Service Routine )이란?

 

  • 인터럽트 서비스 루틴은 해당하는 인터럽트 신호에 대한 로직을 말합니다.

 

  • 인터럽트 서비스 루틴을 수행하기 전에 현재 수행중인 쓰레드의 레지스터 정보를 백업하고 서비스 루틴을 종료하였을 때 이를 다시 업로드합니다.




인터럽트 번호와 인터럽트 벡터( Interrupt Vector )

 

  • 각 인터럽트 신호마다 번호가 다르며 이를 통해 어떤 인터럽트 신호인지 구분합니다.

 

  • 인터럽트 벡터는 인터럽트 서비스 루틴에 대한 주소를 가지고 있으며 인터럽트 번호와 맵핑되어 있습니다.




인터럽트 종류

 

 

  • 인터럽트 종류에는 동기 인터럽트와 비동기 인터럽트로 구분합니다.




동기 인터럽트

 

  • CPU에 의해 발생되는 인터럽트입니다. CPU가 명령어들을 수행하다가 오류와 같은 예외적인 상황에 마주쳤을 때 발생하는 인터럽트가 동기 인터럽트입니다.




비동기 인터럽트

 

  • 주로 입출력장치에 의해 발생하는 인터럽트로서 입출력 장치가 작업을 완료하였을 때 CPU에 완료 인터럽트를 보내 발생하는 인터럽트가 비동기 인터럽트입니다.

 

  • 인터럽트의 우선순위가 낮고 플래그 레지스터를 확인했을 때 현재 인터럽트를 처리할 수 없다면은 인터럽트 요청을 무시합니다.




동기 인터럽트와 예외

 

  • 동기 인터럽트 종류에는 fault, trap, abort, software interrupt 로서 4종류가 있습니다.




fault

 

  • fault 예외가 발생되었을 때 예외를 처리한 후 예외가 발생한 명령어 지점부터 실행을 재개합니다.

 

  • fault로는 대표적으로 Page Fault 예외가 있으며 Page Fault 예외가 발생되었을 때 보조기억장치의 페이징 파일을 확인해서 페이지 아웃된 페이지를 다시 맵핑하고 해당 명령어를 다시 재개합니다.




trap

 

  • 예외를 처리한 직후 예외가 발생한 명령어의 다음 명령어부터 실행을 재개하는 예외입니다. 디버깅을 위해서 trap을 통해 수행중인 코드를 중단시키고 trap을 처리한 후 다음 명령어를 수행하도록 합니다.




abort

 

  • 0으로 값을 나누는 것과 같이 프로세스를 강제로 중단시킬 수밖에 없는 심각한 오류를 발견했을 때 발생하는 예외입니다.




software interrupt

 

  • System Call을 호출하였을 때 유저 모드에서 커널 모드로 전환되는데 이 때 소프트웨어 인터럽트가 발생됩니다.




프로세스 ( Process ) 란?


  • 실행 중인 프로그램을 의미하고 OS로부터 시스템 자원을 할당받는 작업의 단위입니다.

  • 프로세스는 1개 이상의 쓰레드를 가지고 있습니다.




쓰레드 ( Thread ) 란?


  • 프로세스의 메모리 공간을 사용하며, OS의 스케줄링 대상이 되어 퀀텀 타임을 할당받아 CPU에서 실행될 수 있는 단위를 말합니다.




프로세스의 메모리 구조



Code ( Text ) Segment

  • 코드 영역 또는 텍스트 영역이라고도 부릅니다. 해당 영역은 프로그래머가 작성한 명령어가 저장되고 읽기만 가능한 공간입니다.




.rodata Segment

  • 상수 데이터가 저장된 공간이며 읽기만 가능합니다.




Data Segment

  • 초기화된 전역 변수 데이터가 저장된 공간입니다.




BSS ( Block Started by Symbol ) Segment

  • 초기화되지 않은 전역 변수 데이터가 저장된 공간입니다.




Heap

  • 프로그래머가 직접 메모리를 할당하고 반환할 수 있는 공간이며 낮은 주소에서 높은 주소로 할당됩니다.




Stack

  • 지역 변수, 매개 변수, 콜 스택과 같이 데이터를 일시적으로 저장하는 공간이며 높은 주소에서 낮은 주소로 할당됩니다.

  • 스택의 기본 최대 크기는 1MB 입니다.




쓰레드와 프로세스와의 관계



  • 프로세스는 위와 같이 프로세스의 메모리 일부를 스택영역으로 사용하여 실행됩니다.

  • 프로세스는 독립적인 메모리 공간을 가지고 있으며 프로세스 내부에 있는 모든 쓰레드들은 해당 메모리 영역에 있는 모든 데이터에 접근할 수 있습니다.

쓰레드 기아 ( Thread Starvation ) 현상 이란?

  • 현재 레디큐에 있는 쓰레드보다 우선순위가 높은 쓰레드가 지속적으로 레디큐에 인큐되어 해당 쓰레드가 실행될 기회를 얻지 못하는 현상을 말합니다.




Windows가 쓰레드 기아 현상을 해결하는 방법

  • 윈도우는 낮은 우선순위로 인해서 퀀텀타임을 할당받지 못하는 쓰레드들을 대상으로 동적으로 우선순위를 15까지 상승시켜서 스케줄링될 때마다 원래 우선순위 레벨까지 1씩 감소시키는 방식으로 이를 해결하였습니다.

컨텍스트 스위칭 ( Context Switching ) 이란?

 

  • 컨텍스트 스위칭은 현재 수행중인 쓰레드의 레지지스터 상태를 TCB에 있는 레지스터 데이터 블럭에 백업하고 스케줄러에 의해서 퀀텀 타임을 할당받은 쓰레드의 레지스터 상태 값을 CPU 코어에 업로드하는 일련의 과정을 말합니다.

 

  • 컨텍스트 스위칭은 최대한 적게 발생되는 것이 좋습니다. 유저 모드에서 커널 모드로 전환되고 레지스터 상태 값을 백업하고 다시 업로드 하는 과정으로 인해 오버헤드가 발생되어 성능 하락의 원인이 되기 때문입니다.




컨테스트 스위칭의 종류

  • 컨텍스트 스위칭의 종류로는 쓰레드 컨텍스트 스위칭프로세스 컨텍스트 스위칭이 있습니다.




쓰레드 컨텍스트 스위칭 ( Thread Context Switching ) 이란?

  • 동일한 프로세스 내부에 있는 쓰레드간의 컨텍스트 스위칭 ( Context Switching ) 을 의미합니다.




프로세스 컨텍스트 스위칭 ( Process Context Switching ) 이란?

  • 서로 다른 프로세스 내부에 있는 쓰레드간의 컨텍스트 스위칭 ( Context Switching ) 을 의미합니다.




쓰레드 컨텍스트 스위칭 vs 프로세스 컨텍스트 스위칭 성능 차이

  • 프로세스마다 독립적인 주소 공간을 사용하기 때문에 다른 프로세스에 있는 쓰레드 간의 컨텍스트 스위칭이 발생될 경우 그전에 수행하던 쓰레드가 캐시TLB ( Translation Lookaside Buffer ) 에 적재하였던 데이터는 사용하지 못하기 때문에 캐시 hit율TLB ( Translation Lookaside Buffer ) hit율이 떨어져 프로세스 컨텍스트 스위칭보다는 쓰레드 컨텍스트 스위칭이 오버헤드가 상대적으로 적습니다.

 

 

+ Recent posts