● CPU and I/O burst in program Excution
프로그램 실행이 되면 프로그램은 아래와 같은 Path를 실행한다. 프로세스는 CPU에서 기계어가 실행되는 상태와 I/O 작업을 하는 상태의 반복이다. 프로그램마다 다르겠지만 CPU만 쭉 쓰는 프로그램도 있을 거고, 중간에 I/O가 많이 들어오는 프로그램도 있다. 어쨌든 프로그램의 path는 CPU를 쓰는 단계와 I/O를 쓰는 단계가 번갈아가면서 실행한다.
- CPU Burst : CPU만 연속적으로 쓰면스 Instruction을 실행하는 단계
- I/O Burst : I/O를 실행하고 있는 단계
● CPU burst Time
아래 그림은 컴퓨터 안에서 돌아가는 프로그램들의 CPU burst Time을 그래프로 찍어본 것이다. 주로 사람이 Interaction 하는 프로그램이 I/O 작업을 많이 받는 프로그램들이다. CPU burst가 짧은 경우에는 I/O 작업의 빈도수가 높고, CPU burst가 긴 경우에는 빈도가 낮다. CPU를 짧게 쓰고 중간에 I/O 요청이 많이 들어오는 작업을 I/O bound-job이라고 하고, CPU를 길게 쓰고 중간에 I/O가 적게 들어오는 작업을 CPU bound-job이라고 한다.
CPU 스케줄링이 필요한 이유는 CPU Bound Job 문제가 아니라 I/O Bound Job 때문이다. I/O Bound Job은 일반적으로 사람과 Interaction을 하는 작업이기 때문이다. CPU bound-job이 CPU를 잡고 놓지 않으면 I/O bound-job은 CPU를 잡지 못하고 오래 기다리게 되기 때문에 사용자 입장에서는 매우 답답하다. CPU를 공평하게 주는 것도 좋지만 사람과 Interaction을 하는 job에 CPU를 더 우선적으로 주는 것도 필요하기 때문에 CPU 스케줄링의 중요한 역할 중 하나이다. 공평하게 하는 것보다 호율성이 중요하고 Interactive 한 Job이 너무 오래 기다리게 하지 않는 것이 중요하다는 소리다!
- I/O Bound Process : I/O 작업이 많기 때문에 CPU Burst는 빈번하지만 짧아진다.
CPU를 잡고 계산하는 시간보다 I/O에 시간이 많이 필요한 Job (many short cpu bursts)
- CPU Bound Process : I/O 작업이 많이 없기 때문에 CPU를 지속적으로 쓰는 작업이 길어진다.
계산위주의 Job (few bery long cpu bursts)
● CPU Scheduler & Dispatcher
- CPU scheduler : CPU 제어권을 누구에게 줄 것인가
Ready 상태의 프로세스 중에서 이번에는 어떤 프로세스에게 CPU 제어권을 넘겨줄지 고른다.
운영체제 안에서 CPU 스케줄링을 하는 코드가 있는데, 그 부분을 CPU 스케줄러라고 부른다.
- Dispatcher : CPU를 누구한테 줄 지 결정했으니, 그 프로세스에게 CPU를 넘겨주는 역할을 하는 운영체제 커널 코드
CPU 제어권을 CPU 스케줄러에 의해 선택된 프로세스에게 넘긴다.
→ 이 과정을 context switch (문맥 교환)이라고 한다.
프로세스에게 아래와 같은 상태 변화가 있는 경우에 CPU 스케줄링이 필요하다.
- Running → Blocked : 어떤 프로세스가 CPU 제어권을 갖고 있다가 그 프로세스가 I/O 작업과 같은 오래 걸리는 작업을 한 경우, 자진해서 CPU를 내어 놓는 상태
- Running → Ready : 나는 CPU를 계속해서 쓰고 싶은데 할당시간 만료로 Timer Interrupt로 인해 CPU 제어권을 빼앗긴 후, Ready Queue에 줄을 서는 상태
- Blocked → Ready : 오래 걸리는 작업(ex. I/O 작업)이 끝나면 Device Controller가 인터럽트를 걸어서 CPU 제어권을 얻을 수 있는 상태인 Ready Queue에 줄을 서는 상태 (우선 순위가 높으면 이미 실행중인 프로세스가 있다고 하더라도 Ready 상태가 아니라 CPU 제어권을 바로 얻어 Running 상태로 바로 갈 수도 있다.)
- Terminate
→ (1) 번과 (4) 번의 스케줄링은 nonpreemptive(=비선점, 강제로 빼앗지 않고 자진 반납)이고, (2) 번과 (3) 번은 preemptive(=선점, 강제로 빼앗음)이다.
위에서도 말했다시피 CPU 스케줄링은 I/O bound job과 같이 사람과 Interaction을 하는 Job 때문에 필요하다.
CPU 스케줄링은 Ready Queue에 올라와 있는 것들 중 어떤 프로세스에게 CPU 제어권을 넘겨줄 것인가 결정하는 일이다. 그럼 이제 여기서 CPU 제어권을 어떤 프로세스에게 넘겨주어야 더 효율적으로 CPU를 사용할 것인가 하는 생각도 해보아야 한다.
크게 CPU 제어권을 프로세스에게 넘겨주기 전과 후, 두 가지로 생각해 볼 수 있다. 첫 번째는 CPU burst에 들어온 여러 프로세스 들 중 누구한테 CPU를 줄 것인가, 두 번째는 CPU를 프로세스에게 넘겨주었으면 그 프로세스가 다 쓰고 I/O를 하러 나갈 때까지 기다릴 것인가 아니면 CPU burst가 너무 길어서 중간에 CPU 제어권을 다시 빼앗아야 하는가 이다.
- CPU 제어권을 어떤 프로세스에게 넘겨줄 건지 결정
- CPU 제어권을 넘겨 줬으면 계속 쓰게할 것 인가, 아니면 빼앗아 올 것인가를 결정
CPU 제어권을 한 번 넘겨주고 나서 빼앗아 오지 않는다면, CPU burst가 굉장히 긴 프로세스에게 CPU 제어권이 한 번 넘어가면, 그 뒤에 도착하는 I/O bound job들은 CPU를 조금만 주면 바로 쓰고 나갈 Job인데도 불구하고 계속 기다려야 하는 문제가 생긴다. CPU bound Job과 I/O bound job에 따라 효율적인 CPU 스케줄링 방식이 달라진다. 다음 글에서는 스케줄링 알고리즘의 종류를 적어보겠다.