Context Switching(문맥 전환)
Context Switching(문맥 전환)
-
컨텍스트 스위칭은 CPU가 실행 중인 프로세스나 스레드의 상태(
Context)를 저장하고
다음 작업의 상태를 불러와 실행을 재개하는 과정(Switching) -
OS가 ‘멀티태스킹’을 진행하여
여러 프로세스를 동시에 처리하기 위하여 필요! - 프로세스는 PCB (Process Control Block)라는 것을 통해 정보를 저장
- 프로세스 식별자 (PID)
- 프로레스의 상태 (ex : New, Ready, Running, Waiting)
- 프로그램 카운터(PC) 같은 레지스터의 값들 (다음 실행할 명령어 주소)
- 메모리 관리 정보
- Page Table 등
- Page Table 등
- 그 외에도 스케줄링 정보, I/O 상태 등등
- 프로세스 식별자 (PID)
- 스레드는 TCB (Thread Control Block)를 통해 정보 저장
- 스레드 식별자 (TID)
- 스레드 상태 (New,Running,Ready,Waiting)
- PC : 프로그램 카운터
- 스택 포인터 : 각 스레드가 ‘독립적인 스택 영역’을 가지므로
- PCB를 가리키는 포인터 : 공유 자원에 접근하기 위함
- 스레드 식별자 (TID)
- 이러한 PCB, TCB는 ‘커널 영역’에 존재함
- ‘보안’과 ‘안정성’ 때문
- ‘보안’과 ‘안정성’ 때문
프로세스의 문맥 전환이 비싼 이유
- 프로세스는 독립적인 ‘가상 메모리 공간‘을 가짐
- 보호 + 보안
- 보호 + 보안
- 그렇기에 이러한 ‘가상 메모리 공간’에서 ‘물리 메모리 공간’으로 실제 주소를 찾아가기 위해
페이지 테이블이라는 매핑된 테이블이 필요함
- 가상 메모리 공간의 일정 크기 : 페이지 <-> 물리 메모리 공간의 일정 크기 : 프레임
- 가상 메모리 공간의 일정 크기 : 페이지 <-> 물리 메모리 공간의 일정 크기 : 프레임
- 이러한 ‘주소 변환’ 연산을 빠르게 하기 위하여
TLB(Translation Lookaside Buffer) 캐시를 두어
‘가상 주소’ 와 ‘물리 주소’의 쌍을 저장(캐싱)
- TLB는 실제 물리 장치로서 존재하는 페이지 테이블용 캐시!
- PageTable은 DRAM에 존재하며 CPU는
PTBR(Page Table Base Register) 레지스터 (or CR3 레지스터)를 통해 접근
(매 주소 확인마다 DRAM(메인 메모리)까지 내려가는 것은 느리므로!)
- TLB는 실제 물리 장치로서 존재하는 페이지 테이블용 캐시!
- 문맥 전환 자체는 ‘PCB’ 포인터를 변경하는 등 비교적 비싸지는 않지만
TLB Flush(무효화) 및 L1/L2/L3 캐시가 재사용되기 힘듦!
- TLB와 L1,L2,L3 자체에 ‘이전 프로세스’에서 사용한 데이터들로 가득 차있는데
이러한 데이터들은 ‘현재 프로세스’에게는 무의미한 데이터들 - 결국 다시 메인 메모리 or 디스크 에서 캐시를 채워나가기 시작해야 함
- TLB와 L1,L2,L3 자체에 ‘이전 프로세스’에서 사용한 데이터들로 가득 차있는데
그렇기에 스레드의 문맥 전환은 비교적 저렴하다
-
여러 스레드들은 하나의 프로세스의 Code/Data/Heap 등을 공유!
- 다만, 스레드들은 독자적인 Stack 영역을 가짐
- 스레드마다 ‘독립적인’ 함수 호출을 가져야 하기 때문
- 각자 다른 코드를 실행시킴으로서 ‘병렬적인 처리’를 가능하게 함
- 스레드마다 ‘독립적인’ 함수 호출을 가져야 하기 때문
- 그렇기에 스레드의 ‘전환’은 페이지 테이블을 갈아끼울 필요가 없기에 가벼움!
- 기본적인 TCB 포인터 변경 같은 CPU 비용 지불
- 또한 추가적으로 Stack 영역에 대한 캐시가 무효화됨
(그래도 프로세스의 문맥 전환보단 훨씬 가볍다!)
- 기본적인 TCB 포인터 변경 같은 CPU 비용 지불
TMI - CPU는 스레드만을 실행시키고, 프로세스엔 관심이 없다?
-
현대의 OS에서 ‘프로세스’는 일종의 ‘컨테이너’ 역할을 하며
스레드는 실제로 일을 처리하는 ‘일꾼’ 역할을 함 - 그렇기에 CPU는 ‘스레드’를 실행시켜 작업을 진행
(OS 역시 스케쥴링의 대상이 스레드!)
- 위 이미지를 정리하자면 다음과 같음
- OS 스케쥴러가 사용 가능한 CPU 코어에 스레드 할당
- 각 코어는 특정 시점에 하나의 스레드만 실행
- 프로세스 내의 여러 스레드가 존재시, 스레드가 여러 코어에서 동시에 실행 가능
- OS 스케쥴러가 사용 가능한 CPU 코어에 스레드 할당
- 위 이미지를 정리하자면 다음과 같음
- CPU가 작업을 진행하기 위하여
TCB 내부의 PC를 통해 ‘명령어 주소’를 가져오고
PCB 내부의 Page Table Pointer 를 통해 가상<->물리 메모리 매핑만 파악
TMI 2 - OS의 스케쥴링과 인터럽트, 시스템콜?
문맥 전환은
Timer 같은 ‘인터럽트’나
I/O 대기 같은 ‘시스템콜’로 인하여 발생
-
- 인터럽트?
- CPU에게 보내는 신호의 일종으로서
이를 통해 현재 작업을 중단하고, 관련 처리 로직을 실행
- Timer, 키보드 입력 같은 ‘하드웨어 인터럽트’와
Page Fault 같은 ‘소프트웨어 인터럽트’가 존재
- 인터럽트?
-
- 시스템 콜?
- 프로세스가 커널에게 요청하는 일종의 인터페이스(함수)
(정확히는 스레드가 요청하지만 OS의 입장에선 그 스레드 소속인 ‘프로세스’가 요청한 것으로 인식)
- 자원 요청 등의 일을 OS에게 전담
-> 보안, 안정성, 자원 관리에 대한 추상화를 제공
- 시스템 콜?
- Timer 인터럽트?
- OS의 스케쥴링을 위한 인터럽트
(현재 CPU를 독점하는 프로그램에게서 일정 시간마다 CPU 제어권을 OS가 가져옴) - 실제 ‘하드웨어’적 장치(타이머 칩)를 통해 신호를 발생시키기에 ‘하드웨어 인터럽트’로 분류
- OS의 스케쥴링을 위한 인터럽트
- OS는 이러한 Timer 인터럽트를 이용하여
Time Slicing이라는 ‘정책’을 실행 가능함
- 일정한 시간마다 Thread 들의 작업을 번갈아가면서 진행
- 일정한 시간마다 Thread 들의 작업을 번갈아가면서 진행
TMI 3 - 커널?
- OS도 ‘프로그램’!
- 그렇기에 ‘메모리’에 항상 상주하며 ‘핵심 기능’을 수행하는 부분을
‘커널’이라 함
- 그렇기에 ‘메모리’에 항상 상주하며 ‘핵심 기능’을 수행하는 부분을
- 커널의 역할
- 자원 관리 : CPU 스케쥴링, 메모리 할당/해제
- 하드웨어 제어 : 키보드,마우스 등
- 보안과 보호 : 프로세스 간 격리, 접근 권한 파악
- 자원 관리 : CPU 스케쥴링, 메모리 할당/해제
- 커널 모드? 유저모드?
- CPU가 보안을 위해 실행 권한을 나눠둔 것
-
- 커널 모드
- 모든 메모리 및 명령어 사용 가능
OS의 핵심 코드를 실행 가능
오류 발생시, 시스템이 전체적으로 다운
- 커널 모드
-
- 유저 모드
- 제한적인 접근만 허용
프로그래머가 제작한 프로그램 등을 실행
오류 발생 시, 해당 프로그램만 Kill
- 유저 모드
-
- CPU가 보안을 위해 실행 권한을 나눠둔 것
-
- 커널의 위치
- 모든 프로세스의 가상 메모리 상단부에 위치함
- 커널의 위치
- 같은 가상 메모리에 존재해야 하는 이유?
- 같은 프로세스에 존재해야 페이지 테이블을 교체하지 않고 커널 기능 이용 가능
- 커널 접근시마다 페이지 테이블을 바꿔야 한다면 성능 하락
- 커널 접근시마다 페이지 테이블을 바꿔야 한다면 성능 하락
- 같은 프로세스에 존재해야 페이지 테이블을 교체하지 않고 커널 기능 이용 가능
- 이러한 커널의 위치(가상/물리)는
모든 프로세스가 같은 주소를 가지게 됨
(어차피 커널은 모든 프로세스가 공유하므로)
- PageTable을 효율적으로 만들기 위해서!
- TLB 등의 캐시 중 커널 접근에 대한 것은 무효화되지 않음
- TLB 등의 캐시 중 커널 접근에 대한 것은 무효화되지 않음
- PageTable을 효율적으로 만들기 위해서!
댓글남기기