컨텍스트 스위칭
CPU가 현재 프로세스를 중단하고 다른 프로세스로 전환하는 과정
동작 과정
[Process A 실행 중]
↓ 인터럽트/시스템콜
1. A의 상태 저장 (PCB에)
- PC, 레지스터, 스택 포인터
2. 스케줄러: 다음 프로세스 선택
3. B의 상태 복원 (PCB에서)
4. B 실행 재개
Process A OS Process B
[실행 중]
↓ 인터럽트
[A 상태 저장]
[스케줄링]
[B 상태 복원]
[실행 중]
↓ 인터럽트
[B 상태 저장]
[A 상태 복원]
[실행 재개]
PCB (Process Control Block)
| 저장 항목 | 설명 |
|---|
| PID | 프로세스 식별자 |
| PC | 다음 실행할 명령 주소 |
| 레지스터 | CPU 레지스터 값들 |
| 스택 포인터 | 스택 위치 |
| 메모리 정보 | 페이지 테이블 베이스 |
| 프로세스 상태 | Running, Ready 등 |
비용
컨텍스트 스위칭 비용:
직접 비용: ~1-10 마이크로초
간접 비용: 캐시 무효화 (더 큼!)
TLB 플러시 → 페이지 테이블 재로드
CPU 캐시 미스 → 콜드 캐시에서 시작
| 비용 | 프로세스 전환 | 스레드 전환 |
|---|
| 레지스터 저장 | 필요 | 필요 |
| 페이지 테이블 | 전환한다 | 공유한다 |
| TLB 플러시 | 필요 | 불필요 |
| 캐시 영향 | 큼 | 작음 |
→ 스레드 전환이 프로세스 전환보다 가벼움
언제 발생하나?
| 트리거 | 예시 |
|---|
| 타임 슬라이스 만료 | RR 스케줄링 |
| I/O 요청 | read(), network |
| 높은 우선순위 도착 | 선점 스케줄링 |
| 시스템 콜 | fork(), exec() |
실무 영향
| 상황 | 영향 |
|---|
| 스레드 과다 | 전환 오버헤드 증가 |
| CPU 바운드 | 전환 줄이는 게 유리 |
| I/O 바운드 | 전환 빈번해도 OK |
| 코루틴/경량 스레드 | 커널 전환 없이 협력적 전환 |
Q.컨텍스트 스위칭이란 무엇이고 언제 발생하나요?
CPU 가 실행 중인 흐름을 바꾸기 위해 현재 상태를 저장하고 다음 상태를 복원하는 작업입니다.
| 저장하고 복원하는 것 | 내용 |
|---|
| 레지스터 | 범용 레지스터, 프로그램 카운터, 스택 포인터 |
| 커널 자료구조 | 프로세스 제어 블록의 상태 |
| 주소 공간 | 프로세스가 바뀔 때만. 페이지 테이블 기준을 바꾼다 |
발생하는 시점입니다.
| 계기 | 예 |
|---|
| 시간 할당량 소진 | 타이머 인터럽트 |
| I/O 요청 | 대기 상태로 전환 |
| 더 높은 우선순위 등장 | 선점 |
| 인터럽트 처리 | 하드웨어 이벤트 |
| 자발적 양보 | yield, 잠금 대기 |
흔한 실수: 시스템 콜을 문맥 교환과 같은 것으로 답하는 것. 시스템 콜은 같은 프로세스 안에서 모드만 바꾸는 것(모드 전환)이고, 문맥 교환은 실행 주체가 바뀌는 것입니다. 비용도 한 자릿수 차이가 납니다.
Q.프로세스 전환과 스레드 전환의 비용 차이는?
주소 공간을 바꾸는지가 갈림길입니다.
| 항목 | 프로세스 전환 | 스레드 전환 |
|---|
| 레지스터 저장과 복원 | 필요 | 필요 |
| 페이지 테이블 | 전환한다 | 같은 공간이라 그대로 |
| TLB | 무효화된다 | 유지된다 |
| CPU 캐시 | 대부분 쓸모없어진다 | 상당 부분 유효하다 |
직접 비용(레지스터 저장)은 둘이 비슷합니다. 차이는 간접 비용에서 납니다. 주소 공간이 바뀌면 TLB 항목이 무효화되어 한동안 변환 실패가 이어지고, 캐시에 있던 내용도 새 프로세스에는 쓸모가 없습니다.
그래서 같은 프로세스의 스레드끼리 전환하는 것이 몇 배 쌉니다. 다만 스레드가 수천 개가 되면 절대 횟수가 늘어 결국 같은 벽을 만납니다.
흔한 실수: 직접 비용만 비교하는 것. 마이크로초 단위 측정으로는 비슷해 보이지만, 이후 수천 번의 메모리 접근이 느려지는 것이 실제 비용입니다.
Q.컨텍스트 스위칭의 간접 비용(캐시)을 설명해주세요.
전환 자체보다 전환 이후 느려지는 것이 더 큽니다.
| 간접 비용 | 내용 |
|---|
| 캐시 오염 | 새 프로세스가 캐시를 채우며 옛 내용을 밀어낸다 |
| 캐시 재적재 | 원래 프로세스가 돌아오면 다시 메모리에서 읽어야 한다 |
| TLB 실패 | 주소 변환 결과가 사라져 페이지 테이블을 다시 읽는다 |
| 분기 예측 실패 | 예측기가 학습한 패턴이 무효가 된다 |
L1 캐시는 1ns 안팎이고 메모리는 100ns 안팎이라, 캐시가 식으면 같은 코드가 수십 배 느려집니다. 전환 자체가 마이크로초 단위여도 이후 수천 번의 접근이 느려지면 그쪽이 훨씬 큽니다.
측정할 때는 커널이 쓰는 시간 비율을 봅니다. sys 가 user 보다 크면 교환과 시스템 호출에 시간을 쓰고 있다는 신호입니다.
흔한 실수: 문맥 교환 횟수만 보고 판단하는 것. 같은 횟수라도 작업 집합이 캐시에 들어가는지에 따라 체감 비용이 크게 다릅니다.
Q.컨텍스트 스위칭 오버헤드를 줄이는 방법은?
전환 횟수를 줄이거나, 전환이 필요 없는 구조로 바꿉니다.
| 방법 | 내용 |
|---|
| 실행 흐름 수를 줄인다 | 연결마다 스레드 대신 이벤트 기반으로 |
| 스레드풀 | 생성과 소멸을 없애고 개수에 상한을 둔다 |
| 코어 고정 | 특정 스레드를 특정 코어에 묶어 캐시를 유지한다 |
| 배치 처리 | 작은 작업을 모아 한 번에 처리한다 |
| 논블로킹 I/O | 대기로 내려가지 않게 한다 |
| 경량 실행 단위 | 코루틴처럼 커널을 거치지 않는 전환을 쓴다 |
첫 번째가 가장 효과가 큽니다. 동시 연결 2,000에 연결당 스레드를 두면 커널이 이들을 번갈아 실행하는 일 자체에 CPU 가 소진됩니다. 이벤트 기반으로 바꾸면 실행 흐름이 코어 수만큼만 남습니다.
흔한 실수: 스레드를 무조건 줄이는 것. I/O 대기가 긴 작업은 스레드가 적으면 대기만 하다 처리량이 떨어집니다. 대기 비율에 맞춰 정해야 합니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
운영체제 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.