목차
컨텍스트 스위칭이란
우리는 멀티 코어 환경에서 하나의 프로세스에서 여러 스레드가 동작하는 환경에 익숙해져있다.
하지만 실제 스레드를 실행하는 실질적인 주체인 CPU(코어)에 비해 스레드가 더 많다면,
결국 CPU 자원을 할당받지 못한 스레드는 대기 상태가 되어야 한다.
하지만 운영체제의 스케줄링에 의해 대기 중이던 스레드는 다시 CPU에 의해 코드를 실행할 수 있다.
이 일련의 과정을 통해 스레드들은 번갈아 가며 수행된다는 사실을 알 수 있다.
이처럼 CPU 개수보다 스레드 개수가 많을 때, CPU의 사용처가 한 스레드에서 다른 스레드로 전환되는 과정을 컨텍스트 스위칭이라고 한다. CPU 입장에서는 A라는 스레드에서 B라는 스레드로 전환될 경우, 작업하던 문맥인 컨텍스트가 변경되는 것이기에 컨텍스트 스위칭이라고 한다.
CPU는 작업 중이던 하나의 스레드를 전환해야 한 뒤로 나중에 해당 스레드를 다시 사용해야 한다.
즉, 컨텍스트 스위칭이 발생하기 전에 기존에 작업 중이던 상태를 메모리에 저장하고, 전환해야 한다. 따라서 컨텍스트 스위칭에는 비용이 발생할 수 밖에 없다.
CPU와 스레드의 비율에 따라 발생할 수 있는 상황들
CPU 6개, 스레드 3개
CPU(코어)의 개수는 6개, 스레드는 3개라면 3개의 CPU가 각각 하나의 스레드를 담당하면 된다.
이 때는 물리적으로 3개의 작업을 동시에 실행할 수 있게 된다. 또한, 스레드에 비해 CPU가 많기 때문에 컨텍스트 스위칭이 비교적 적게 일어나므로 컨텍스트 스위칭 비용도 적을 것이다.
하지만 CPU에 비해 스레드 개수가 적으므로 CPU 자원을 100% 활용하지 못하게 된다. 즉, 놀고 있는 CPU가 많다는 문제가 있다.
CPU 6개, 스레드 200개
이번에는 CPU 개수에 비해 스레드 개수가 30배 가량 많다. 이럴 경우, 앞선 케이스와 달리 CPU 자원을 100% 활용할 수 있다. 즉, 놀고 있는 CPU가 생기지 않게 되며, 모든 CPU가 다수의 스레드를 처리하기 위해 바삐 움직일 것이다. 다만, 각 CPU는 여러 스레드를 조금씩 순차적으로 실행하기 때문에 (멀티 태스킹) 컨텍스트 스위칭이 잦을 것이며, 해당 비용도 많이 발생할 것이다.
CPU 6개, 스레드 6개
스레드의 개수가 CPU의 개수와 일치하기 때문에 CPU의 자원을 100% 활용하면서 컨텍스트 스위칭 비용도 발생하지 않는 이상적인 상황이 된다. CPU 코어보다 1개 더 많은 스레드를 배치하면 하나의 스레드가 대기할 때, 다른 스레드를 실행할 수 있게 된다. (CPU와 스레드를 최적으로 활용)
하지만 그렇다고 해서 스레드의 개수를 CPU 개수에 맞추기 위해 수를 줄일 경우, 서비스 운영에서 큰 문제가 생길 수 있다. 그 이유는 다음 절에서 설명하겠다.
스레드가 처리하는 작업
CPU-바운드 작업
바운드(bound)는 '한정된'이란 뜻으로 CPU-바운드란 CPU 자원을 최대한으로 사용해야 하는 작업을 말한다. CPU의 연산 능력을 요구하는 작업으로는 계산, 알고리즘 수행, 데이터 처리 등이 있다.
I/O-바운드 작업
I/O-바운드란 입출력(I/O)이 중요하고, 이를 많이 요구하는 작업을 뜻한다. 이러한 작업은 I/O가 완료될 때까지 대기시간이 발생하며, CPU의 사용량이 CPU-바운드 작업보다 비교적 적다. 따라서 CPU가 많이 사용되지 않고, 대기하는 시간이 많이 발생한다. 즉, 스레드가 CPU를 사용하지 않고, I/O가 완료될 때까지 대기한다. 주로, DB 쿼리 처리, 파일 읽기/쓰기, 네트워크 통신, 사용자 입력 처리 등이 있다.
웹 어플리케이션에서의 스레드
백엔드 개발자로서 스레드가 주료 사용되는 환경은 웹 어플리케이션 서버(WAS)일 것이다. 사용자의 요청 하나를 처리하기 위해 하나의 스레드가 사용되는데, 스레드 개수가 많을 수록 여러 사용자의 요청을 동시에 처리할 수 있다. WAS의 경우, CPU를 최대한 활용하여 계산을 하거나 알고리즘을 수행하기 보다는 사용자의 입력을 처리하거나 DB 쿼리를 날리거나 외부 API 연동을 위해 네트워크 통신을 하는 등 I/O 바운드 작업이 빈번하다. 즉, 스레드가 CPU를 많이 활용하기 보다는 I/O를 위한 기다리는 시간이 더 많다. (이게 핵심!)
만약, 이러한 상황에서 스레드 개수를 CPU 개수와 일치시킨다면 어떻게 될까? 분명 WAS에서의 스레드는 CPU를 많이 활용하지 않는다고 했다. 따라서 하나의 CPU가 하나의 스레드를 맡게 되는 상황이 온다면 우리는 CPU를 최대 5% 조차도 활용하지 못하는 일이 발생하며, 동시에 처리할 수 있는 요청의 개수도 그만큼 줄어든다.
적절한 스레드의 개수를 찾는건 실무 환경에 따라 다르다! 따라서 테스트 서버의 성능 테스트를 통해 적절한 스레드 개수를 찾는 것이 중요하다. 단순히 장비의 퀄리티를 높이는 것이 능사가 아니라 현재 주어진 CPU 성능을 최대한 활용할 수 있도록 충분한 스레드가 생성되어 있는지를 점검하는 것이 중요하다.
정리
CPU 바운드 작업
(스레드가 CPU 자원을 많이 활용하는 경우)
스레드를 CPU 숫자에 최대한 맞춘다. (CPU 개수보다 1개 많은 정도) 왜냐하면 스레드가 CPU 자원을 대부분 활용하기 때문에 CPU 대비 스레드 개수가 많아져 버리면 컨텍스트 스위칭 비용이 많이 발생한다.
I/O 바운드 작업
(스레드가 CPU를 비교적 적게 활용하는 경우, I/O 대기를 더 많이 하는 경우)
CPU 개수보다 훨씬 더 많은 스레드를 생성한다. CPU 자원을 최대한 활용할 수 있을 정도의 스레드 개수를 생성한다. 각 스레드별로 CPU의 자원을 거의 사용하지 않기 때문에 CPU 개수보다 훨씬 많은 스레드 개수를 생성하는 것이 적절하다. 물론 너무 많은 스레드를 생성해버리면 컨텍스트 스위칭 비용이 발생하기 때문에 성능 테스트를 통해 적정량을 찾는 것이 중요하다.
참고 자료
'CS > 운영체제' 카테고리의 다른 글
프로세스와 스레드 (0) | 2024.08.13 |
---|---|
멀티 태스킹과 멀티 프로세싱 (0) | 2024.08.12 |
주기억장치 관리 (0) | 2022.04.26 |
프로세스(Process) 관리 (0) | 2022.04.26 |
운영체제(Operating System)란 (0) | 2022.04.25 |