Monday, April 7, 2008

Advanced Process Management - process scheduling

프로세스 스케쥴링에서 멀티테스킹을 지원하는 경우 아래의 두가지 방법이 있다.
  • preemtive multitasking(선점형)
  • cooperatice multitasking

cooperative 멀티테스킹에서는 프로세서가 스스로 yield (다른 프로세스로 스위치 하도록) 하지 않는 이상 계속적으로 프로세서 자원을 사용할 수 있다. preemptive에서는 커널이 '선점형' 이기 때문에 특정 프로세스가 일정 timeslice이상을 사용하지 못하도록 제어할 수 있다.

linux의 scheduling algorithm은 O(1)이다. 즉 프로세스의 수가 늘어나도 스케쥴링을 위해 소요되는 시간은 일정하다.

Timeslice 는 너무길거나 짧을 경우 둘다 문제가 된다. 너무 짧을 경우 context switch 하는 비용이 많아지고, 캐시의 temporal locality가 떨어진다. 너무 길게 되면 User Interactivity가 떨어지게 된다.

Processor bound & I/O bound. 프로세스가 할당된 timeslice를 거의 다 사용하는 경우 processor bound 이고, 대부분 파일, 키보드 입력, 마우스 등의 I/O작업인 경우 I/O bound 이다. 전자의 경우 캐시 hit를 늘이기 위해 되도록 많은 timeslice를 사용하여 작업을 마치기 원하고, 후자의 경우에는 짧게 짧게 작업이 이루어지는데 스케쥴러가 빨리 다시 작업을 시작해주도록 해주기를 원한다. Linux Scheduler는 프로세서의 각각 특징에 따라 다른 방식으로 프로세스들을 다루려고 노력한다(주로 IO bound에 대해서는 우선 순위를 높여주고, processor bound에는 penalty를 준다).

Idle Process는 실제 프로세스가 아니다. Idle process는 커널이 자신의 scheduler algorithm을 재조정하는 시간이다. idle time은 이러한 idle process를 돌리는데 소용된 시간이다.

Thread에 대해서 잠깐 생각해보면, Linux에서는 Thread를 같은 주소 공간을 공유하는 프로세스로 간주한다(Thread라고 별다르게 생각하지 않는다). 대부분의 개발자들은 thread 프로그래밍을 위해 IEEE에서 제정한 thread API인 API pthreads를 사용한다.

Yielding processor 란 '나 끝났어, 딴 프로세스 돌려' 라고 알려주는 것이다. 말그대로 프로세서를 양보하는 것인데, 아래 함수를 통해 할 수 있다(별로 일반적이지는 않다).



#include <sched.h>

int sched_yield(void);

이 system call을 사용해서 일종의 non-block한 코드를 구현할 수도 있겠지만, 그리 좋은 방법은 아니다(그냥 non-block 을 지원하는 함수를 쓰는 편이 낫다). 이전에 thread를 구현할 때 user space에서의 thread locking을 구현하기 위해 잠시 사용하기도 했으나, 근래에는 futex로 user space locking이 지원되고 있다.

프로세서가 서로 yield를 해서 ping pong pathological case가 발생할 수 있다. 하지만, 2.6이후 버전에서 yield 알고리즘을 개선하여 이런 문제를 해결하였다.

No comments:

Post a Comment