2023. 12. 21. 15:25ㆍ운영체제/쓰레드와 스케쥴링
[ 작성 이유 ]
운영체제이 미치는 영향 중 프로그램의 성능과 가장 관련이 있는 게 Scheduler가 아닐까 싶다. 우선 이것에 대해서 잘 이해하고 싶다면 메모리의 계층 구조와 프로세스의 state에 관한 지식을 알고 있어야지 이해가 쉬울 것이라고 생각한다. 배경지식을 설명한 후에는 Scheduler에 관해서 설명을 하겠다. 많은 Scheduler가 있지만 간단하게 기존 Scheduler의 문제점만 이야기를 하고 넘기고 가장 핵심인 CFS scheduler와 Multiprocessor Scheduling에 대해서 알아보면 왜 쓰레드의 개수와 작업 속도가 꼭 비례하지 않는 지를 알 수 있다. 책에선 Process로 설명을 하니 프로세스로 설명하지만 이건 쓰레드에도 적용이 된다.
[ 배경지식1 - 메모리의 계층 구조 ]
컴퓨터의 메모리 구조는 CPU 내의 register, cache메모리, 그리고 보조기억장치(RAM)과 주기억장치(DISK)로 구성되어있다. 그림으로 나타내보면 아래와 같다.
이를 계층 피라미드로도 나타낼 수 있지만 이 그림이 더 좋다고 생각을 한다.
우선 속도적인 측면에서는 좌측에서 우측으로 갈수록 좋다. 해당 장치들의 속도와 용량은 반비례한다. 특히 속도가 빠르다는 건 용량이 작다는 걸 의미하고 용량이 크다는 건 속도가 느리다는 걸 의미한다.
컴퓨터 프로그램이 돌아간다는 것은 Memory 역할을 하는 보조 기억장치(RAM)에서 돌아간다. CPU는 자신이 지금 담당하고 있는 프로그램을 CPU에서 작동시키며 이 때 사용했던 내용 중 자주 접할 것 같은 내용들을 CPU cache에 저장하고 현재 연산 중인 instruction 정보를 register에 저장한다.
이 때 만약에 OS의 Scheduler에 의해서 Context Change가 일어나면 기존 프로세스의 상태를 저장하고 CPU 내부에 있는 캐시 데이터를 변경한다. 또한 다음 프로세스의 저장된 상태를 불러 일으키고 해당 코드와 데이터를 Memory에 다시 올린다.
위 과정에서의 비용은 얼마나 많은 내용을 바꾸느냐에 달려있다. 그렇기 때문에 https://intellectum.tistory.com/75 프로세스와 쓰레드에 관해서 설명을 이전에 한 것이며 더 많은 내용을 가지고 있는 프로세스보단 쓰레드가 더 비용이 작으며 OS들은 쓰레드 단위로 Scheduling을 한다.
그렇다고 모든 작업이 CPU와 Memory 사이에서 일어나는 것은 아니다. RAM과 CPU의 특징은 빠른 대신 휘발성이 있다. 그렇기 때문에 전원이 꺼져버리는 경우 데이터를 복구할 방법이 없다. 그래서 중요한 내용 혹은 영구 저장할 내용을 DISK에 저장한다. 이걸 앞으로 설명할 FILE I/O 과정으로 생각하면 되며 이 작업은 CPU와 이루어지는 것이 아니기 때문에 CPU 자원을 사용하지 않아도 된다. 이 부분을 기억했으면 좋겠다.
[ 배경지식 2 -프로세스의 State ]
리눅스의 프로세스 state에는 더 많은 종류가 있지만 하단의 그림만으로 설명을 하려고 한다.
1. Running: 프로세스가 현재 작동 중으로 현재 CPU가 작업 중인 프로세스임을 의미한다. 다른 특별한 일이 없이 작업 시간이 끝나면 Runnable state로 바뀌어서 대기 중인 프로세스를 담는 자료구조에 들어가게 된다.
2. Ready: 하단의 그림에서는 Ready 상태는 프로세스 대기열에 들어가 있는 상태로 Scheduler의 알고리즘에 따라서 결정되면 결정에 따른 프로세스가 다음에 Running 상태로 이동하게 된다.
3. Blocked: Sleeping, Waiting 같은 상태가 있지만 포괄적으로 Blocked라고 표현을 했다. Blocked는 이미지처럼 I/O를 위해서 프로세스에서 본인의 I/O가 끝날 때까지 있는 상태, 다른 프로세스의 종료를 기다리는 Join 같은 걸 호출하는 상태 같은 상황을 의미한다. 해당 상태가 끝나면 신호를 받고 다시 Scheduling될 가능성이 있는 Ready 상태로 변경되게 된다.
[ Scheduler ]
Scheduler를 이해하기 위해서는 CPU와 Process에 관해서 생각을 해보아야 한다. Virtual Memory에 관해서 배워보면 알겠지만 실제 메모리에는 여러 개의 프로세스가 할당이 된다. 실제로 작동을 할 때에는 여러 프로세스가 작동하는 것처럼 보이지만 매우 찰나의 순간에 프로세스가 운영체제에 의해서 Scheduling이 되면서 계속 바뀌지만 그 순간이 매우 짧기 때문에 인식을 하지 못한다.
OS의 Scheduler에 의해서 작업하는 프로세스가 변경되는 과정을 Context Switch라고 한다. 이 때 일어나는 일은 현재 작업 중인 프로세스의 상태를 저장하고 다음 진행할 프로세스의 상태를 가져와서 복구한다. 또한 Cache 초기화, Memory Mapping 초기화가 일어난다. 특히나 매우 반복적인 활동을 하는 프로세스일수록 Context Switch가 자주 일어나면 성능이 나빠진다. 그렇다면 좋은 Scheduler라는 것은 과연 무엇일까?
[ Turnaround Time ]
좋은 Scheduler가 가지는 첫번째 덕목은 도착시간과 완료시간의 차이가 짧아야 한다. 즉, Turnaround Time이 빨라야 한다. 이 관점에서 본다면 수많은 Scheduling 관련 알고리즘 중에서 FIFO(First Come First Out)나 STCF(Shortest Time-to-Complition First) Scheduling은 일어나면 안된다.
그 이유는 FIFO면 먼저 들어온 작업이 매우 길면 나중에 일어날 작업은 그걸 한참동안 기다려야 한다. 마치 1차선 고속도로가 있는데 그 고속도로에서 경운기 하나가 시속 20km로 달리고 있는 상황이라고 생각하면 된다. 그렇다고 STCF면 중간에 짧은 작업이 무한하게 계속 추가되는 긴 작업은 OS로부터 영원히 할당되지 못한다. 그렇기 때문에 이 방식의 Scheduler는 실제 상황에 적합하지 않다.
[ Response Time ]
좋은 Scheduler가 가지는 두번째 덕목은 처음 작업을 하는 시간과 도착시간의 차이가 짧아야 한다. 즉 Response Time이 짧아야 한다. 어떤 작업이 되었건 각각의 작업이 길면 Response Time은 굉장히 길다. Response Time이 문제를 해결하는 가장 쉬운 방법은 작업을 특정 단위로 쪼개는 방법이다. 실제로 xv6 같은 코드를 작업해보면 알겠지만 tick이라는 단위가 있고 scheduler 알고리즘에 따라서 할당되는 프로세스의 시간이 다르며 할당된 시간만큼의 tick을 지나게 되면 context switching이 일어나게 된다.
이렇게 Scheduling을 하면 얻는 장점은 첫 번째로는 응답시간이 빨라진다. 두번째는 실제 상황에서는 해당 프로세스가 언제 끝나는지 예측하는 것은 사실 불가능하다. 결과적으로 작업을 쪼개면 응답시간과 작업 시간을 예측할 필요가 없어진다.
쪼개면 모든 게 해결이 될까? 아니다. 쪼개기만 하고 RR 방식으로 Process를 계속 돌려버리면 Turnaround Time은 오히려 나빠질 수 있다. 또한 Process의 생명주기의 blocked상태로 넘어가는 것처럼 데이터를 영구저장하기 위해 Disk I/O가 일어나면 그동안에는 CPU에서 그 프로세스를 할당할 필요가 없다. 왜냐하면 CPU가 필요없는 작업이기 때문이다. 한정된 자원인 CPU를 바쁘게 일하게 시키려면 이 과정에서 더이상 CPU가 필요가 없으니 Disk I/O가 작업이 끝나면 알리고 그 때까지 CPU는 다른 처리 가능한 프로세스를 처리해야 한다.
이를 처리하기 위해서 고민된 방법이 MLFQ(Multi-level Feedback Queue)이다. MLFQ는 우선 순위를 설정해놓고 우선 순위가 같은 것끼리는 RR 방식으로 처리를 한다. 우선 순위를 통해서 I/O하는 프로세스의 우선 순위를 뒤로 미루고 끝나면 다시 높임으로써 위에서 설명한 상황을 처리할 수 있다. 하지만 이 과정에서는 몇 가지 추가적으로 필요한 게 있는데 새로 들어온 프로세스에 대한 우선 순위처리, time slice 별 프로세스 처리, 특정 시간에 따른 우선 순위 초기화 등의 문제가 발생하지만 이 부분은 참고자료 내의 정리된 내용이 더 좋은 것 같으니 참고자료 맨 아랫 자료를 읽어보길 바란다.
[참고자료]
https://velog.io/@profile_exe/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Queue-Swap
'운영체제 > 쓰레드와 스케쥴링' 카테고리의 다른 글
운영체제 공부 4 - scheduler 3 ( 멀티프로세스 scheduler ) (0) | 2023.12.28 |
---|---|
운영체제 공부 3 - Scheduler 2(CFS) (0) | 2023.12.21 |
운영체제 공부 1 - Process와 Thread (2) | 2023.12.21 |