본문 바로가기
나도 공부한다/운영체제

05. CPU scheduling

by 꾸빵이 2021. 5. 31.

cpu scheduling이란? CPU를 더 효율적으로 사용하기 위한 것. 프로세스 스케줄링을 위한 queue에는 job queue, ready queue, wait queue가 있다.

 

 

프로세스 스케줄링의 과정

  • 새로운게 들어오면 먼저 레디큐로 간다. 레디큐에서 스케줄러를 통해 CPU로 가고 목적에 따라 I/O(I/O를 요청한 디바이스들의 웨이팅 큐에서 I/O를 기다리다가 I/O 작업을 수행), time slice expired(타이머가 끝났을때), fork a child(일반적인 wating queue에 들어가서 child가 끝날때까지 기다림), wait for an interrupt(특정 interrupt 발생을 기다림) 등의 작업을 수행한다. 수행이 끝나면 다시 레디큐로 들어감
  • CPU burst(CPU 작업을 하는 단계) -> I/O burst(기다리는 단계) 가 반복됨. 이때 주어진 시간보다 더 많은 시간이 걸리는 작업을 하면 중간에 작업을 강제로 내리고 switching한다. (이럴 경우 context switching이 두번 일어남)
  • I/O burst에서는 wait queue에서 I/O 작업을 기다림.
  • CPU burst에서는 ready queue에서 CPU 작업을 수행함. 작업이 끝나면 자발적으로 wait.
  • wait -> ready -> terminated 순서로 종료하므로 언제나 CPU 베스트에서 종료가 됨. (CPU 베스트란? 주어진 시간보다 작업이 빨리 끝나서 CPU burst가 context switching이 일어나지 않은 것)

 

CPU burst Time

 ex) 대부분이 8 미만의 짧은 CPU 작업을 한다고 가정하자. 이때 CPU burst time을 5로 잡으면 작업을 하던 도중 끊기는 일이 빈번하여 context switching이 더 자주 일어나서 오버헤드가 발생함. time을 16으로 늘리면? 작업을 끝내고 스스로 내려오는 경우가 많아 context switching 빈도가 낮아짐. 여기서 더 늘리면? 작업 시간에 비해 지나치게 많은 시간을 준 것 이므로 공정성이 떨어짐.

=> 적절한 time을 찾아야함!

 

 

ready queue와 waiting queue의 개수

 레디큐는 프로세스별로 하나씩 / 웨이팅큐는 여러개. 웨이팅 큐를 사용하면 disk에서 신호가 왔을때 어떤 프로세스가 wait를 원하는지 끝까지 순환하며 찾아내야함. 웨이팅큐에 unit을 연결하면 마그네틱에게 작업 종류에 관한 신호를 받고 그 번호를 기다리는 프로세스들만 검색해주면 wating을 원하는 프로세스를 빨리 찾을 수 있음. ex) unit 0은 마그네틱 0번에게 신호를 받아 0번을 기다리는 프로세스를 검색함

 

 

Schedulers

  • Short-term scheduler(=CPU scheduler)
    위에서 이야기한 스케줄러를 말함. 레디큐에 있는 작업중 하나를 고르는 것. 밀리단위임.
  • Medium-term scheduler
    degree of multiple program(얼마나 많은 프로세스를 메모리에 올릴 수 있냐는 것. CPU util을 계속 높게 유지)을 적절히 맞춰주는 역할. 분단위.
    너무 오래 웨이팅 할때 등 비효율적인 일이 발생하면 프로세스를 교체함. 기존에 있는 프로세스를 스토리지로 억지로 내리고 다른 것을 메모리로 올림.
    ex) 아래의 표를 보면 I/O 시간이 실행 시간보다 훨씬 길다. 따라서 실행을 금방 끝내고 나면 남은 CPU가 없으니 스토리지를 살펴서 새로운 작업을 찾게 된다.(롱텀 스케줄러) 100동안 동작하는 P4 작업을 찾았다고 가정하면 P1+P2+P3+P4=124이므로 P4까지 CPU 작업을 할 동안 P1의 I/O는 끝이난다. P4가 끝나면 다시 P1 작업을 시작한다. =>CPU util이 계속 높게 유지됨!

      P1 P2 P3
    실행 시간 10 8 6
    I/O 시간 100 1000 10
  • Long-term scheduler(=Job scheduler)
    스토리지에 있는 job중에 어떤걸 메모리로 올릴지 고름. 시간단위임.
    롱텀 스케줄의 역할은 적절한 process mix를 만드는 것.
    프로세스가 종료될떄마다 메모리 공간이 충분히 확보되면 long-term 스케줄러가 동작하여 storage에 있는 작업을 프로세스화 함.
  • 옛날 OS는 이 세가지가 계층적으로 구성됨. 요즘에는 Short-term scheduler만 사용됨.
    옛날 OS와 요즘 OS는 메모리 공간의 차이가 있음. 옛날 OS는 메모리에 있지 못하고 스토리지에 감.
    더보기
    타임슬라이스란? 프로세스에게 할당해주는 시간. 타임 슬라이스마다 스케줄러가 실행됨. 작업이 자발적으로 웨이팅큐에 간 상황이면 타임슬라이스보다 짧게 동작했다는 것임.타임슬라이스란? 프로세스에게 할당해주는 시간. 타임 슬라이스마다 스케줄러가 실행됨. 작업이 자발적으로 웨이팅큐에 간 상황이면 타임슬라이스보다 짧게 동작했다는 것임.

 

 

스케줄러의 동작 두가지

  • Non-preemptive(비선점형)
    강제로 내릴 수 없는 것. 프로세스가 자발적으로 CPU를 놓을때까지 계속 기다림.
    waiting queue로 들어가거나 terminated 될때.
    switching이 최소화되지만 공평성이 부족함.
  • All other scheduling is preemptive(선점형)
    타이머가 있어서 강제로 내릴 수 있는 것. boosting 매커니즘이 가능함.
    프로세스에게 우선권을 주기 위해 강제로 내리는 권한을 쓰는 것임.
    동기화 문제가 발생함.(동작중인 프로세스를 갑자기 내렸을때)
    ex) OS가 동작중(커널 모드 상태)에도 CPU를 빼앗길 수 있음 -> 커널쉐어데이터가 불안정한 상태로 마무리됨
    ex)A라는 프로세스가 파일을 열어 작업중이었는데 프림티브 스케줄러가 A를 강제로 중단시킴. B라는 프로세스가 스케줄링되어 A가 쓰다만 파일에 접근하려는데 접근하지 못함.(한 파일을 하나의 process만 열 수 있다고 가정) B는 파일을 언제 열 수 있는지 계속 체크만 하다가 자신의 타임 슬라이스를 다 쓰고 다시 레디큐로 돌아감.
    -> B에게 CPU를 준 의미가 없다. 이런 식으로 불필요하게 CPU를 낭비하는 경우가 발생. A가 작업중이면 뺏지 않는 동작 필요.

Dispatcher(별로 안 중요)

숏텀 스케줄러에서 스위칭하고 다른 프로세스로 전환해주는 코드를 말함.

숏텀 스케줄러 안에서 실제로 context를 바꿔줌.

 

Scheduling Criteria

  • CPU를 평가하는 지표를 말함.
  • CPU utilization) 스케줄러의 목표는 CPU utilization을 최대로 높게 하는 것
  • Throughput) 특정한 단위시간동안 몇개의 프로세스가 완료되었는지 볼 수 있음. ex) 한 시간동안 백개의 프로세스가 완료됐다
  • Turnaround time) 어떤 프로세스를 수행시키는데 걸린 총 시간 (프로세스가 시작한 시간~ 끝난 시간)
  • Waiting time) Turnaround time중 웨이팅큐에서 기다리는 시간
  • Response time) 어떤 요청이 왔을때 해당 프로세스가 그 요청에 응답하기까지 걸린 시간. (=프로세스가 시스템에 로딩된 시간. 프로세스가 로드되고 맨처음 스케줄링 받기까지 걸린 시간) / 인터렉티브 프로세스는 응답시간이 낮게 나오길 기대함. 스케줄러가 웨이팅 큐에서 레디큐로 온 프로세스를 빠르게 스케줄링할 수록 응답시간은 낮아짐.

Scheduling Algorithm Optimization Criteria

  • Max CPU utilization ) context switching을 적게 할수록 높아짐. 높을수록 좋음.
  • Max throughput
  • Min turnaround time ) 짧을수록 중간에 웨이팅 타임이 없음.
  • Min waiting time )
  • Min response time ) context switching을 많이 할수록 낮아짐.
  • 이것들을 한번에 달성할 수 없음!! 메인 요구사항에 맞춰야함.
  • ex) 슈퍼컴퓨터는 CPU를 최대한 활용해야하므로 CPU utilization을 본다.
    ex) 사용자가 요청했을때 최대한 빠르게 답을 주는 것이 중요하므로 Response time을 준다.

Scheduling Algorithms

  • First-Come, First-Served Scheduling (FCFS)
  • Shortest-job-First Scheduling (SJF)
  • Priority Scheduling
    -----------가장 기본적인 배치시스템-----------
  • Round-Robin Scheduling
  • Multilevel Queue Scheduling
  • Multilevel Feedback Queue Scheduling
    -----------더 복잡한 배치시스템------------

FCFS

  • 순서대로 스케줄링함.
  • 오래걸리는 것이 뒤로갈 수록 waiting time, average waiting time이 줄어듦.
  • 마트 계산대에서 나는 살게 많고 뒷사람은 하나만 있다고 가정했을때 내가 차례를 양보하면 난 조금 더 기다리지만 전체적으로 기다리는 시간이 짧아지는 것과 같은 이유.

 

SJF

  • 짧은 순서로 스케줄링함.
  • 평균 대기시간을 줄이는데에 가장 이상적인 방법. BUT 실제로 다음 버스트 타임을 잘 모르기 때문에 달성하기 어려움. CPU에 올려봐야 버스트 타임을 알 수 있음. 이 방법을 쓰려면 버스트 타임을 예측해야함.
  • CPU 바운드=CPU 버스트 긺.
  • I/O 바운드=CPU 버스트 짧음.

 

Shortest-remaining-time-first

  • SJF에 arrival time을 추가함. remaintime을 따져서 더 조금 남은 프로세스를 실행시킴.
  • ex) 8만큼 수행하는 P1이 1까지 실행하던 도중 4만큼 실행하는 P2가 들어온 상황이면 P1을 프림션 시키고 P2를 수행함. 이후로 들어오는 P3, P4와 비교해봤을때도 P2가 더 짧으면 P2는 프림션되지않고 burst time이 0이 될때까지 수행함.

 

Priority Scheduling

  • burst time은 신경쓰지 않고 오직 우선순위만 봄. (우선순위는 사용자에 의해 결정됨. 따라서 유저의 의도가 정확히 반영되는 스케줄링)
  • 높은 우선순위를 가지는 이유는 시스템 작업을 하는 프로세스이거나 사용자가 그 프로세스의 우선순위를 일시적으로 높게 했기 때문임.
  • SJF는 priority 방식이기도 함. 다만 우선순위를 부여할때 CPU burst time의 역수를 취해서 그것을 priority number로 삼음.(=CPU burst가 길수록 낮은 priority를 가짐)
  • 낮은 우선순위는 영원히 실행이 안 되는 Starvation문제가 발생함.
    ex) P1 실행도중 우선순위가 더 높은 P2가 들어옴. 그럼 P1은 프림션되고 P2가 실행됨. P2가 끝나면 다시 P1 실행. 그런데 P1보다 우선순위가 더 높은 프로세스가 계속 들어오면? P1은 실행을 못함.
    -> 우선순위를 높여줌(Aging 기법) 실행 도중 끼어드는 프로세스가 발생할 때 마다 원래 실행중이던 프로세스의 우선순위를 -1함.

 

Round Robin (RR) Scheduling

  • 라운드가 반복되면서 스케줄링하는 것.
  • 위에서 말한 기법들은 주로 배치 시스템에 이용됨. 타임 쉐어링에서는 RR을 사용함.
  • 사용이유) 프로세스들이 CPU burst만하고 끝나는 것도 아니고, CPU burst는 계속해서 바뀔 수 있으므로 위에서 말한 것들은 현실적인 알고리즘이 아님.
  • 라운드 로빈이라는 틀 안에서 각 라운드마다 다른 스케줄링 방식을 쓸 수 있다. (어떤 알고리즘을 쓰는지 반드시 명시)
  • 단위는 퀀텀으로, 할당할 수 있는 가장 작은 단위임. 1퀀텀=1ms라고 가정하고 퀀텀을 ms단위로 표현함.
    때문에 1ms 이하의 스케줄링은 할 수 없음. 1ms 단위라서 그 중간엔 OS가 개입할 수 없음.
    타임 퀀텀이 1이라는 말은, 1ms가 되었을때 타이머 interrupt가 오고 CPU가 interrupt를 받아서 OS에게 처리할 것을 요청한다는 것임. OS가 깨어나서 현재 동작중인 프로세스가 타임 슬라이스를 얼마나 썼는지 확인하고 다 썼으면 내리고 다른 프로세스를 올림. 즉, 1ms마다 OS가 상태를 확인한다는 
  • 라운드 크기는 유동적이고 돌릴때마다 바뀔 수 있음.
  • H/W 타이머 설정에 따라 필요시에 그때마다 커널이 스케줄링됨.
  • 각 라운드마다 타임 슬라이스가 부여됨. (라운드마다 해당 프로세스가 쓸 수 있는 시간이 부여됨)
    ex) 타임 슬라이스를 각 프로세스마다 10개씩 줬다=각 타임 슬라이스는 10ms=10 of time quantum
  • 각 프로세스들이 타임슬라이스를 다 쓰면 라운드가 종료됨. 현재 프로세스가 끝나고 다음 프로세스가 시작될때 각 프로세스들의 타임슬라이스를 리필함.
  • P1에는 4ms, P2에는 2ms, P3에는 3ms의 타임 슬라이스를 부여함. 현재 레디큐에서 대기하고 있는 프로세스가 P1, P2, P3이라고 하면 라운드 길이는 9ms.
  • 타임슬라이스를 어떻게 부여할 것인가? 타임 슬라이스는 context switch을 고려해 충분히 커야한다. 안 그러면 오버헤드 발생.
    1. 아주 길게 => FIFO 방식이 됨
    2. 짧게 => responsiveness는 높아지지만 성능은 낮아짐. CPU를 비효율적으로 쓰게됨.
    ex) P1 P2 순서로 실행된다고 가정하자. 이때 P1은 30ms 동안 동작하고 P2는 10ms 동안 동작한다. 한 라운드에 P1, P2에게 주어진 타임 슬라이스는 각 3, 1이다. 총 10라운드가 실행되어야 끝나는 것이다. context switching이 많이 발생한다. 타임 슬라이스를 30, 10으로 늘리면? 1라운드만에 실행이 끝난다. 이것은 FIFO를 쓴 것과 다름없다. context switching은 한번 발생한다. 이에 따른 오버헤드도 더 적게 발생하고 CPU utilization이 좋아짐. 반면에 response time은 느리다. 클릭을 하면 P2에서 반응이 온다고 가정하자. 각 타임 슬라이스가 3, 1인 프로세스에서 P1이 실행되는 도중에 클릭을 해도 곧 P2 프로세스가 스케줄링되므로 response time이 짧다. 타임 슬라이스가 30, 10인 프로세스는 P1 실행도중에 클릭을 하면 P2가 실행되기까지 많은 시간이 걸리므로 response time이 길다.

 

Multilevel Queue

  • 레디큐가 여러개 있는 것. 실제 시스템들은 대부분 이걸 사용함. 큐마다 다른 알고리즘을 사용함.
  • 시스템에는 여러가지 특성을 가진 프로세스들이 동시에 돌아감. 
    응답률이 중요한 프로세스들은 RR로 스케줄링해야함. CPU utilization이 중요한 프로세스들은 FIFO로 스케줄링해야함. 이 상황에서 둘을 어떻게 동시 스케줄링할것이냐?
  • 두가지 큐가 있는데, 첫번째 큐는 foreground 큐이고 interactive 프로세스를 관리하기 위한 큐. RR 스케줄링으로 동작. 두번째 큐는 background 큐이고 배치 프로세스(CPU 바운드 프로세스)를 관리하기 위한 큐. 두 큐를 번갈아가며 동작시킨다. 첫번째 프로세스를 먼저 실행시키고 더 이상 레디큐에 작업이 없으면 두번째 프로세스를 동작함. 두번째 큐의 사용시간이 지나면 다시 첫번째 프로세스 동작.
  • Fixed priority scheduling) 여러 큐에 우선순위를 부여하고 높은 우선순위에 존재하는 여러개의 큐 안의 프로세스들이 전부 수행되어야 다음 레벨의 큐를 수행함.
  • 대부분의 OS들은 두 세개의 큐로 나눔.
    system processes) 이 안에 있는 프로세스들이 CPU 시간을 다 써버림. 그럼 아래에 있는 프로세스들은 전혀 실행이 안됨.(fixed priority Scheduling) 너무 중요한 작업이라 강력한 방식을 쓰는 것으로, 어쩌다가 한번 발생함.
                                                                    ↓
    interactive processes
                                                                    ↓
    interactive editing processes
                                                                    ↓
    batch processes) 위의 세개가 다 수행되어야 배치 프로세스가 수행된다고 생각할 수 있는데 실제로 대부분의 경우엔 배치 프로세스가 기본적으로 수행되고 있고 어쩌다가 한번씩 저런 프로세스가 생기면 빠르게 처리함.
                                                            

Multilevel Feedback Queue

  • 실제로는 사용하지 않음. 시스템 프로세스가 쓰는 특별한 클래스임. 우리가 쓰는 건 대부분 제너럴한 프로세스.
  • 단점) CPU 바운드 프로세스와 interactive process를 큐 안에 넣어줘야함. 특성에 따라 큐를 만들어 놨는데, 돌리기 전까지는 모른다는 모순이 발생함. -> 프로세스가 각각의 큐에서 벗어나 다른 큐로 이동할 수 있게 만들어줌.
  • 프로세스가 생성되면 첫번째 큐에 그냥 넣어줌. 작업이 끝나고 안 빠져나오고 주어진 시간을 다 써야 CPU burst가 길다고 판단하여 다음 큐로 넘김. 
    두번째 큐에서 주어진 슬라이스를 다 안쓰면 interactive한 작업이라고 판단함. 반대로 타임 슬라이스를 다 쓰면 I/O할 생각이 없는 CPU 바운드 프로세스라고 판단하여 FCFS로 넘김.
    FCFS로 넘어왔는데 I/O burst로 빠지면서 자꾸 웨이팅큐로 넘어가면 다시 첫번째 큐로 돌아감.
    => CPU 바운드인줄알고 넣었는데 시간이 지나고 interactive한 프로세스로 바뀌었구나!

 

 

'나도 공부한다 > 운영체제' 카테고리의 다른 글

06. CPU-IPC  (0) 2021.06.05
05. CPU Scheduling (2)  (0) 2021.06.01
04. CPU  (0) 2021.05.31
03. 운영체제의 구조와 설계  (0) 2021.03.29
02. 컴퓨터 시스템  (0) 2021.03.18