Quick Flow
running thread blocks, yields, or is preempted
-> save execution context
-> scheduler selects a runnable thread
-> restore its context
-> resume executionContext switch는 현재 실행 상태를 보존하고 다른 thread의 상태를 복원하는 전환입니다. 전환 자체의 비용뿐 아니라 cache와 TLB locality가 깨지는 간접 비용도 생길 수 있습니다.
Thread 상태
실행 가능한 thread가 모두 동시에 CPU를 사용하는 것은 아닙니다. 대략 running, ready, waiting 같은 상태를 오가며, I/O나 lock을 기다리는 thread는 CPU를 소비하지 않고 대기할 수 있습니다.
Scheduler는 priority, affinity, fairness, 전원 정책과 운영체제 규칙을 바탕으로 실행 대상을 정합니다. 애플리케이션이 특정 실행 순서를 관찰했다고 다음 실행에서도 같은 순서가 보장되는 것은 아닙니다.
Thread 수 판단
CPU-bound 작업은 runnable thread가 core보다 과도하게 많으면 전환과 경쟁이 늘 수 있습니다. I/O-bound 작업은 대기 중인 실행 흐름이 많아도 유용할 수 있지만, 현대 비동기 I/O에서는 요청마다 전용 thread를 둘 필요가 없는 경우가 많습니다.
Thread 수를 줄이거나 affinity를 고정하기 전에 profiler에서 ready time, wait reason, CPU utilization, context switch와 실제 작업량을 함께 봅니다.
자주 틀리는 점
- context switch 동안 CPU가 언제나 완전히 아무 일도 하지 않는다고 표현하지 않습니다. 전환 자체도 kernel 작업입니다.
- 높은 priority를 성능 향상 수단으로 남용하지 않습니다. 다른 thread starvation을 만들 수 있습니다.
Sleep(0)이나 yield가 특정 thread로 실행권을 넘긴다고 보장하지 않습니다.- thread 생성 비용과 매 작업의 context switch 비용을 같은 것으로 보지 않습니다.
참고 링크
2 sources